在自己的malloc函数中调用printf导致分段错误
我想用Linux GCC在纯C中“重写”在自己的malloc函数中调用printf导致分段错误,c,memory,segmentation-fault,printf,malloc,C,Memory,Segmentation Fault,Printf,Malloc,我想用Linux GCC在纯C中“重写”malloc,用于内存检查。请注意,malloc()是一个弱符号,在纯C中这样做是可以的。例如,制作一个malloc()的强符号 但我刚刚发现,如果在我的malloc()实现中调用printf(),它会崩溃,如果删除,它不会崩溃 复制: #include <stdio.h> extern void *__libc_malloc(size_t size); static int cnt = 0; void* malloc(size_t si
malloc
,用于内存检查。请注意,malloc()
是一个弱符号,在纯C中这样做是可以的。例如,制作一个malloc()
的强符号
但我刚刚发现,如果在我的malloc()
实现中调用printf()
,它会崩溃,如果删除,它不会崩溃
复制:
#include <stdio.h>
extern void *__libc_malloc(size_t size);
static int cnt = 0;
void* malloc(size_t size) {
printf("--- calling customized malloc\n");
cnt += 1;
if(cnt > 1) return NULL;
return __libc_malloc(size);
}
static void leak_test1() {
int* a = malloc(sizeof(int)*5);
a[0] = 3;
}
int main(){
leak_test1();
printf("cnt=%d\n", cnt);
return 0;
}
#包括
外部无效*uuu libc_umalloc(大小);
静态int cnt=0;
void*malloc(大小){
printf(“---调用自定义malloc\n”);
cnt+=1;
如果(cnt>1)返回NULL;
返回uu libc_malloc(大小);
}
静态空隙泄漏试验1(){
int*a=malloc(sizeof(int)*5);
a[0]=3;
}
int main(){
泄漏测试1();
printf(“cnt=%d\n”,cnt);
返回0;
}
这是否意味着“在我自己的malloc()中调用printf无效”?深层次原因是什么?(如果我错了,请纠正我)有可能
printf
调用malloc
为stdout
分配缓冲区,因此您会得到无限递归
您可以通过调用
fprintf(stderr,…)
来绕过这个问题,因为stderr
是无缓冲的。我怀疑printf
调用malloc
来分配其缓冲区,在这种情况下,您会创建一个无限递归。您可能需要为输出绕过stdio,或者在malloc
返回后将其排队并打印出来。如果printf
调用malloc
,则创建了一个递归循环并炸毁了堆栈。@TomKarzes是的,我还认为printf调用malloc,从而递归调用…我将变量cnt
,但是我应该在调用printf
之前检查cnt
。尝试用put
替换printf
-cnt应该做什么?向上计数直到引发整数溢出?这是一个bug。printf怎么知道被叫方翻译单元中的malloc呢?为了使用malloc,它必须从“stdio.c”标准库中包含stdlib.h,在这种情况下,malloc是正确的,而不是“重载”的。您所描述的行为应该只有在printf的整个函数都是类似于宏的情况下才可能发生,我对此表示怀疑。我宁愿怀疑这一点:库中的malloc函数定义不是命名为malloc
,而是其他名称。然后在stdlib.h中,它们有一些技巧,既有正确的malloc
函数声明,也有一些宏通过调用内部“something\u else\u malloc”(允许标准库这样做)来重载函数声明。但是,当调用方实际提供名为malloc
的函数定义时,该函数定义被链接,宏技巧中断。在那之后,您描述的无限递归是可能的。否则,如果stdlib malloc也被命名为malloc
,那么程序甚至不应该链接。@Lundin:您所描述的是可能的,但我怀疑malloc
不是一个带有
中某些属性的简单外部声明。弱符号和动态符号解析的精确语义对我来说有些模糊,甚至在linux环境中,对大多数程序员来说也可能是陌生的。我建议使用一个简单的测试来检查缓冲是否是问题所在(不是一个正式的证明,而是一个强有力的指示)。OP没有对这个建议发表评论,但接受了答案,所以我的建议一定解决了问题。