为什么这段代码只会导致零售业崩溃?

时间:2011-07-08 02:06:45

标签: c++ c

这个代码显然存在问题,但它只会导致零售而不是调试中的访问冲突。任何具体原因? VS 2008是编译器。假设enabled = true

void parse(bool enabled)
{
  char* p = NULL;
  if (enabled)
  {
     char a[100] = 'jsajas';
     p = &a;
  }
  if (p != NULL)
  {
     p[0] = 'a';
  }
}
编辑:我知道失败的原因。我想知道是什么导致它在零售业中崩溃而不是在调试中崩溃。如何以不同的方式处理内存。

编辑:略微编辑代码,以便更清楚我的问题是什么。

编辑:恢复旧代码并在下面添加新代码,因为人们似乎不喜欢它。很抱歉引起混淆。我的目的是在堆中分配时真正理解该问题。

void parse(bool enabled)
{
  char* p = NULL;
  if (enabled)
  {
     char* a = new char[100];
     a[0] = 'a';
     p = a;
  }
  if (p != NULL)
  {
     p[0] = 'a';
  }
}

5 个答案:

答案 0 :(得分:3)

在控制流退出声明范围后,您正在访问变量(数组a)。这是未定义的行为

MSVC可以生成非常不同的代码,具体取决于您使用的是Release还是Debug。有可能:

  • 在调试模式下,编译器为函数
  • 中任何地方声明的所有变量在堆栈上分配足够的空间
  • 在发布模式下,编译器会在输入和退出作用域时生成更改堆栈上分配的内存量
  • 的代码

为了找到答案,您可以查看生成的汇编代码。

答案 1 :(得分:2)

语句应该是p = a;一个数组已经是一个指针,你告诉p是一个指针的指针,这就是你访问一些奇数内存位置的原因。在这个数组的顶部a是在一个范围内声明的,这是未定义的,一些编译器预先分配它并且它将正常工作,其他人只在if语句的范围内执行一次。

答案 2 :(得分:2)

应为char a[100] = "abcd"(注意双引号)

应为p = ap = &a[0]

当然,只要a超出第一个}的范围,数组对象就不再有效。所以这是Undefined Behavior,它可以很容易地与一个编译器,编译器版本或一组开关一起工作,并与另一个开关崩溃。

答案 3 :(得分:1)

未定义未定义的行为。它可能会崩溃,垃圾堆栈,或只是正常进行。没有押韵或理由,因为它是 undefined 。它可以在不同的构建中做不同的事情;没有任何保证。因此,术语“未定义”。

这就是为什么你应该坚持使用定义的行为。

答案 4 :(得分:-1)

void parse(bool enabled)
{
  char* p = NULL;
  if (enabled)
  {
     char* a = new char[100];
     a[0] = 'a';
     p = a;
  }
  if (p != NULL)
  {
     p[0] = 'a';
  }
}

您修改过的代码看起来不错。但是你没有释放从堆中分配的100个字节。指向分配的内存的指针(包括a和p)在此函数之外是未知的。这意味着此功能之外的任何人都无法解除分配。

内存泄漏。