【问题标题】:C++: not getting segfaults when I should be [duplicate]C ++:当我应该[重复]时没有得到段错误
【发布时间】:2013-06-11 20:09:51
【问题描述】:

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

#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]);
    }   
}

【问题讨论】:

  • 为什么会出现段错误?
  • 越界访问是未定义的行为。没有要求你得到一个段错误。
  • 重复数百次。
  • 你还没有在调试模式下编译它..

标签: c++ segmentation-fault


【解决方案1】:

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

malloc 取自构成堆的更大的预分配内存块。例如。系统可能会以 4K 块为单位创建(或增加)堆,因此超出数组边界的范围仍将位于已分配给进程的堆内存块内(并将从中分配内存以供后续使用malloc)。

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

【讨论】:

  • 这些你都无法确定。
  • @peter:有时“很可能”是一个足够好的解释。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:
      1. 应该使用new 而不是malloc
      2. 什么是平台?
      3. 当您尝试未定义的行为时 - 猜猜它是未定义的。

      【讨论】:

      • 不是新的 malloc 语法糖吗?
      • @Maksim - 否 - 首先它会在必要时调用构造函数,并且可能底层机制使用不同的方法来分配内存。
      猜你喜欢
      • 2014-01-24
      • 1970-01-01
      • 1970-01-01
      • 2018-06-06
      • 2020-06-15
      • 2015-02-04
      • 2021-08-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多