这是一段 C 代码:
int main()
{
void **values = calloc(10, sizeof(void *));
int *a = malloc(sizeof(int));
*a = 100;
int *b = malloc(sizeof(int));
*b = 200;
values[0] = a;
values[1] = b;
values[0] = NULL;
free(values);
values[1] = NULL;
free(values);
free(a);
free(b);
return 0;
}
问题是:为什么不会导致分段错误呢?因为它试图到达禁区。当然
Valgrind
会详细显示错误,但运行程序不会出现任何错误。
我还使用
void **values = calloc(1, sizeof(void *));
运行了代码并得到了相同的结果。
另外,如果您尝试将 values[1] = NULL
更改为 values [2]
(使用 10 个 void*
块),它会抱怨分段错误。
当您尝试访问已释放的内存,或尝试多次释放内存时,会在代码中触发未定义的行为。
如果行为未定义,您的程序可能会崩溃,可能会输出奇怪的结果,或者(如您的情况)它可能看起来工作正常。此外,进行看似无关的更改(例如添加未使用的局部变量或添加 printf 进行调试)可以改变未定义行为的表现方式。
仅仅因为程序可能崩溃并不意味着它将会。