为什么这段代码有用?

时间:2014-07-03 00:11:31

标签: c++

#include <iostream>
#include <string>
using namespace std;


class CExample {
public:
  int a,b,c;
  void setvalue(int n, int m);
  void multiply() { 
  c = a*b;
  cout<< c <<endl;
  };
};

void CExample::setvalue(int n, int m){
  a = n; b = m;
}

int main( )
{

  CExample *d = new CExample[1];
  d[0].setvalue(2,30);
  d[0].multiply();
  d[1].setvalue(2,30);
  d[1].multiply();
  d[2].setvalue(2,30);
  d[2].multiply();
  delete[] d;
  return 0;
}

由于我只为数组d分配了1个内存资源,因此在操作d [2]时应该会遇到错误。但是,编译器没有报告错误或警告。结果是正确的。

有人可以解释为什么会有效吗?

感谢

是的,这是未定义行为的魔力。谢谢你们所有人。

3 个答案:

答案 0 :(得分:3)

C ++编译器无法捕捉到编写错误代码的所有可能方式。

在运行时,C ++程序通常不会在您访问内存超出范围时抛出错误。该语言并非旨在保护程序员不做坏事。

所以当一个程序做这样的事情......这是未定义的行为......任何事情都可能发生。那&#34;什么&#34;可以包括出现正常工作&#34;。或者可能会立即出现奇怪的行为。但无论哪种方式都是错误的。如果它似乎有效,那只能靠运气。

在实践中,它也可能在某处破坏内存,最终会导致其他问题。也许问题没有时间在小例子程序中体现出来。但程序越大,出现某种不良症状的可能性就越大。

最后,C ++对程序员负有很大的责任,要编写正确的代码,这些代码不会超出数组范围。

答案 1 :(得分:0)

有人可以解释它为什么有效吗?” - 您认为代码有效。

我在操作d [2] 时应该遇到错误” - 你认为代码应该做的不是它做的事情。

你正在提出两个相互矛盾的说法。你说的是代码的工作原理以及代码应该做的事情。这些都不是真的。

如您所知,您的代码存在错误。所以它没有达到预期效果就不足为奇了。

答案 2 :(得分:0)

  1. 您使用取消分配内存,这是一种未定义的行为。
  2. 这是一个运行时错误,因此编译器无法捕获它。 使用内存检查工具valgrind,您将收到“无效写入”错误。