C 堆内存布局

C 堆内存布局,c,memory,layout,fault,C,Memory,Layout,Fault,我正在开发一个相当复杂的c程序,它使用结构的链表。在我的一个.c文件(队列头)的顶部声明了一个全局变量。该变量现在被神秘地覆盖,从而导致seg故障 有没有办法找出我的变量在内存中的布局。我对原因的最佳猜测是,某些内容正在写入其内存的末尾,并覆盖队列头内存位置 为了测试我在源文件中颠倒了queue_head和queue_tail的位置,下一次运行程序时,queue_tail被破坏了,但是queue_head没有问题 当然,它可能是一个错误的指针,但我相信,它背后的一些东西在内存中被写入到过去的内存

我正在开发一个相当复杂的c程序,它使用结构的链表。在我的一个.c文件(队列头)的顶部声明了一个全局变量。该变量现在被神秘地覆盖,从而导致seg故障

有没有办法找出我的变量在内存中的布局。我对原因的最佳猜测是,某些内容正在写入其内存的末尾,并覆盖队列头内存位置

为了测试我在源文件中颠倒了queue_head和queue_tail的位置,下一次运行程序时,queue_tail被破坏了,但是queue_head没有问题

当然,它可能是一个错误的指针,但我相信,它背后的一些东西在内存中被写入到过去的内存分配中

有没有办法查看c如何映射出没有反汇编的变量?

从大多数编译器(或更可能的链接器)中,您可以生成一个.map文件,该文件将列出所有全局变量和函数

您没有提到您使用的编译器,但对于gcc,它将回答您的问题

基本上,将其添加到gcc行:

 -Xlinker -Map=output.map 

变量通常按文件中的出现顺序排列,但若程序有多个文件,那个么就很难预测。您可以打印他们的地址以查找可能的罪犯:

printf("%p %p\n", &queue_head, &fishy_var);
但找到前一个变量有什么好处呢?很可能是坏代码没有直接引用它

更好的方法是使用调试器。例如,若您可以在gdb中运行程序,那个么您可以使用监视点在内存损坏的位置断开:
监视队列\u head
。之后,该程序会在每次队列头的值发生变化时中断,包括合法使用。要隔离合法使用,请在队列头之前添加伪指针变量并观察它:

void *fishy_var;
queue *queue_head;
然后在gdb中:

break main
run
watch fishy_var
continue
这将直接导致违规代码


注意,您最好将我在main开头显示的printf设置为1。确保变量在内存和2中是连续的。确保编译器不会优化掉未使用的fishy_var。

我相信,OP正在寻求一种方法来获得运行时变量的内存布局。事实上,这正是我想要的。我记得我在c语言编程早期的一些东西,比如地图文件。我现在不买,但不知道有什么选择。我正在使用gcc。我对两个答案都投了赞成票,因为这两个答案都适用于这个问题。这一个最好地回答了我特别提出的问题。这可能会帮助你-。是的,我明白你在说什么。昨晚我又把它搞砸了,在文件的同一个位置又放了几个变量。我能够将所有令人不快的覆盖内容转换成我添加的一些虚假INT,然后可以读取它们。那里有字符串数据,这有助于隔离代码。以后才能再处理,但我开始知道错误在哪里了。再次感谢。我之所以选择这个答案,是因为它带来了解决方案。我以前没有用过gdb。这是一本很棒的入门书。对于来到这里的其他人,我将只添加一些我需要的要点,以使其工作。将CFLAGS+=-g添加到Makefile中,以便可执行文件中包含调试信息。我的可执行文件需要args来重现问题,为此,您运行gdb--args。。。最后,由于我的程序每次在StrucPy中间中断,请输入BT或回溯以找到可执行文件中的行来修复。它列出了调用堆栈和确切的行。