我正在编写一个宠物项目(一种类似 Lisp 的单线程 C 语言解释器),我遇到了以下问题:运行 malloc()
时指针被覆盖。显示所有代码会太长,但如果有必要我可以分享。我想了解如何调试问题。
该错误发生在运行用户定义函数的子例程期间:
/* Determine the amount of arguments to the called function */
int argc = ast_len(fn_args)
printf("%s:%d %p\n", __FILE__, __LINE__, (void*) scope->vars->tail);
/* Allocate the memory to store the array of pointers to each of the arguments */
struct YL_Var** argv = malloc(sizeof(struct YL_Var*)*argc);
printf("%s:%d %p\n", __FILE__, __LINE__, (void*) scope->vars->tail);
您将得到以下输出:
interpreter.c:549 0x5558371c9480
interpreter.c:551 0x411
Segmentation fault (core dumped)
指针scope->vars->tail
在调用malloc()
期间被覆盖!
使用 gdb 和硬件断点清楚地表明该值在 malloc.c 内部被覆盖。
当指针被覆盖时,程序很快就会出现段错误,无论是在 gdb 内还是在正常运行中。然而,当在 valgrind 中运行时,它不会出现段错误,甚至会成功结束。 这是我的问题。您将如何开始调试这个困惑的情况?我是在寻求建议,而不是寻求答案。 我距离 C 专家还很远:)
我想我有错,这当然不是 glibc-2.26 或 gcc 7.2.0 中的错误。
- 我在使用
-Wall -Wextra -Wpedantic
时没有收到关于 gcc 的警告 - valgrind 显示一些未释放的内存问题。在做其他事情之前会修复它们。
最佳答案
感谢大家的评论,我找到了问题。
scope->vars
没有适当分配(正如一些人所说)。
使用 valgrind
时,我发现以下消息:
==23054== Invalid write of size 8
==23054== at 0x10A380: varlist_prepend (interpreter.c:277)
==23054== by 0x109548: main (yl.c:39)
==23054== Address 0x5572a98 is 0 bytes after a block of size 8 alloc'd
==23054== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23054== by 0x10A304: varlist_prepend (interpreter.c:274)
==23054== by 0x109548: main (yl.c:39)
==23054==
我的代码如下所示:
struct YL_VarList* vars = malloc(sizeof(vars));
如您所见,*
丢失了。
这是更正后的版本:
struct YL_VarList* vars = malloc(sizeof(*vars));
sizeof(vars)
将返回 struct YL_VarList*
的大小,而我想分配 struct YL_VarList
的大小。
关于c - 运行 malloc 后内存损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47794591/