我在尝试获取合法指针中的数据时遇到了segmentation fault
的奇怪场景。我有一个名为p
的INTEGER
指针,每当我试图使用*p
获取p
中的数据时,我都会遇到分段错误。
我试着用GDB
找出这个问题。而在GDB
中,即使我可以使用print *p
获得正确的数据,内存引用仍然抛出SIGSEGV
我的代码片段如下:
int *p = (int*)malloc(sizeof(int));
// some other codes
printf("%dn", *p);
当然,p
不是NULL
。因为我在打印前检查了NULL
。但我不能确定它是否指向某个无效的位置。因为中间的代码太大了,很难找到。有没有什么方法可以检查它是否指向随机位置?
为了确保它没有指向某些随机位置,我在malloc
之后和printf
语句之前打印了p
中的地址,它们似乎是相同的。所以我认为这个地址不是随机的。此外,GDB print
还提供了我所期望的正确数据。
我在malloc之后和printf语句之前打印了p中的地址,它们看起来是一样的。
要绝对确定它们是一样的有多难?
说真的,你需要一个理性的方法,而不是说"救命,我有很多代码,我不知道问题可能在哪里"——没有人能帮你提供这些信息。
那么,你能做些什么合理的事情呢?
您可以开始在任何位置插入printf("ZZZZ %s: %d: %dn", __FILE__, __LINE__, *p);
。printf
不会在malloc
之后立即崩溃,但在某个时刻它会崩溃。祝贺你:你刚刚缩小了问题的范围。
更快的方法可能是在Valgrind或AddressSanitizer下运行程序:这些工具通常会直接导致问题。
至于实际问题是什么,我怀疑您的malloc
实际上分配了几MB的数据,而不是您所显示的4字节,对于如此大的块,glibc将调用mmap
。如果稍后free
该数据,glibc将munmap
块,并使内存不可访问。下次尝试打印*p
(它将访问悬挂的指针)时,会出现分段错误。