c - 运行 malloc 后内存损坏

标签 c pointers memory-corruption

我正在编写一个宠物项目(一种类似 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 内部被覆盖。

Assembly in GDB HW breakpoint in GDB

当指针被覆盖时,程序很快就会出现段错误,无论是在 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/

相关文章:

c - 我程序中的段错误

c - 在 C 中创建套接字时出错 (Visual Studio 2017)

c - void * 指针是否用于 C 中的泛型类型?

C编程: ouput two strings as two columns next to each other

C、字符串数组不会弃用从字符串常量到 'char*' 的转换

c - 带有 realloc() 的 printf() 会使程序崩溃

c++ - 堆损坏 - Vector push_back

c - 为什么 C 标准 bool 不是 bool_t?

c - strcpy 和数组的意外行为

使用静态 vector 连续调用 R 函数 .C(),是否需要继续强制转换数据类型?