-2

在注意到另一个项目中发生了一些奇怪的事情后,我写了以下内容。即使数组被多次调用越界,此代码也不会产生段错误。有人可以向我解释为什么运行下面的代码没有段错误吗?

#include <stdlib.h>
#include <stdio.h>
int main()
{
    int *a = (int *)malloc(4 * sizeof(int));
    int *b = (int *)malloc(3 * sizeof(int));
    int i = 0;
    for(i =0; i <3 ; i++)
    {   
     b[i] =  3+i;
    }   
    for(i = 0; i < 4; i++)
    {   
     a[i] = i;
    }   
    for(i = 0; i < 100 ; i++){
     a[i] = -1; 
    }   
    for(i = 0 ; i < 100 ; i++){
    printf("%d \n", b[i]);
    }   
}
4

4 回答 4

2

未定义的行为是未定义的。任何事情都可能发生,包括“正确”行为的出现。

于 2013-06-11T20:12:31.973 回答
2

仅当您尝试访问未映射到进程中的内存位置时才会发生段错误。

malloc 取自构成堆的更大的预分配内存块。例如,系统可能会在 4K 块中创建(或增加)堆,因此超出数组的边界仍将位于已分配给进程的堆内存块内(并且将从该块分配内存)随后的mallocs)。

在不同的情况下(之前分配了更多内存,因此您的 malloc 接近堆块的末尾),这可能会出现段错误,但基本上不可能预测这一点(尤其是考虑到不同的平台或编译器)。

于 2013-06-11T20:13:51.413 回答
1

当进程尝试访问操作系统认为不属于该进程的内存时,就会发生分段错误。由于操作系统内部的内存统计是按页面(通常 1 页 = 4 KB)完成的,因此进程可以访问已分配页面内的任何内存,而操作系统不会注意到它。

于 2013-06-11T20:13:08.747 回答
1
  1. 应该使用new而不是malloc
  2. 平台是什么?
  3. 当您尝试未定义的行为时 - 猜测它是未定义的。
于 2013-06-11T20:13:49.937 回答