gpt4 book ai didi

c - 内存分配违规后 free() 的奇怪行为

转载 作者:太空狗 更新时间:2023-10-29 16:01:50 25 4
gpt4 key购买 nike

不久前,我在我编写的某个大型数字库中寻找错误,这让我花了很多时间。问题是我违反了某些结构成员的内存边界,但不是 段错误 或只是普通的崩溃,它做了一些意想不到的事情(至少我没想到)。让我举个例子:

segmentation_fault.c

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>

#define N 100 /* arbitrary large number */

typedef unsigned char byte;

void exitError(char *);
void segmentationFaultSignalHandler(int);

sig_atomic_t segmentationFaultFlag = 0;


int main(void)
{
int i, memorySize = 0;
byte *memory;
if (setvbuf(stdout, NULL, _IONBF, 0))
exitError("setvbuf() failed");
if (signal(SIGSEGV, segmentationFaultSignalHandler) == SIG_ERR)
exitError("signal() failed");
for (i = 0; i < N; ++i)
{
printf("Before malloc()\n");
if ((memory = malloc(++memorySize * sizeof(byte))) == NULL)
exitError("allocation failed");
printf("After malloc()\n");
printf("Before segmentation fault\n");
memory[memorySize] = 0x0D; /* segmentation fault */
if (segmentationFaultFlag)
exitError("detected segmentation fault");
printf("After segmentation fault\n");
printf("Before free()\n");
free(memory);
printf("After free()\n");
}
return 0;
}


void segmentationFaultSignalHandler(int signal)
{
segmentationFaultFlag = 1;
}


void exitError(char *errorMessage)
{
printf("ERROR: %s, errno=%d.\n", errorMessage, errno);
exit(1);
}

正如我们所见,memory[memorySize] = 0x0D; 行显然违反了 malloc() 给定的内存边界,但它不会崩溃或引发信号(我知道根据 ISO C99/ISO C11,信号处理是实现定义的,并且在违反内存边界时根本不必提高)。它继续打印 After segmentation faultBefore free()After free() 行,但经过几次迭代后它崩溃了, 始终在 free() (打印 After segmentation faultBefore free(),但不打印 After free()).我想知道是什么导致了这种行为,以及检测内存访问违规的最佳方法是什么(我很惭愧,但我总是有点用 printf 来确定程序崩溃的位置,但肯定有更好的工具来做到这一点)因为它很难检测(通常它不会在违规代码处崩溃,但是,如示例所示,在代码的后面,当再次尝试使用此内存执行某些操作时)。当然,我应该能够释放这 block 内存,因为我正确地分配了它并且没有修改指针。

最佳答案

您只能在伪造的环境中检测违规行为。在这种情况下,您违反了从系统中获得的内存,您将无法再相信任何事情。因为现在发生的所有事情都是未定义的行为,你不能期望会发生什么,因为没有任何规则。

因此,如果您想检查程序是否存在内存泄漏或某些读/写违规。您必须编写一个程序来获取属于它的内存区域,并将该区域的一部分提供给“待检查”程序。您必须检查进程并跟踪它写入和读入我们内存的位置,并且您必须使用内存的另一部分来检查是否允许在那里读写(即在您的伪造环境中通过设置一些 FLAGS 并检查它们是否已更改)。

因为如果程序离开你拥有的区域。你不能确定你是否会检测到这种行为。所以你必须自己做内存管理来检查这种行为。

关于c - 内存分配违规后 free() 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21330233/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com