访问冲突读取位置0xcdcdcdcd - VS 2010 win7

时间:2012-12-22 11:04:13

标签: c++ visual-studio-2010 pointers memory matrix

经过很长一段时间我都在做C ++,有些事情让我很烦恼。我在这里发现了类似的问题,但没有一个能解决我的问题。那么,这笔交易是什么?

我有

SomeClass*** world;

表示SomeClass对象的指针矩阵。

后来,在构造函数中,当我尝试初始化它时,就像这样做

for(int i = 0; i<20;i++)
    for(int j = 0;j<20;j++)
        world[i][j] = new SomeClass();

它打破了消息:访问冲突读取位置0xcdcdcdcd。 我读了这条消息可能意味着什么,但我仍然不知道如何让它发挥作用。

提前致谢!

3 个答案:

答案 0 :(得分:4)

我认为在声明变量时理解你获取的内容非常重要。就像在内存中实际创建的一样。

让我们来看看SomeClass*** world;。这得到什么你?它能为您提供指向SomeClass的指针矩阵吗?不,它没有。事实上,你可能会惊讶地知道这只会让你有一件事 - 一件事 - 一个指针。是的,没错,只有一个指针。你已经定义了这个world变量,它是一个指针,而这就是你从中获得的所有变量。那个单指针。

然后应该使用此指针指向其他指针,而这些指针又指向指向SomeClass的指针。但是,它指出的那些东西还不存在。因此,当您将ij重复到20并执行world[i][j]时,您将尝试访问尚不存在的指针矩阵。

现在,为了使你所写的工作仍在使用SomeClass***,你需要分配指针矩阵:

world = new SomeClass**[20];
for (int i = 0; i < 20; i++) {
  world[i] = new SomeClass*[20];
}

首先我们分配一个20 SomeClass**的数组,然后我们让每个指针指向一个20 SomeClass*的已分配数组。这给你你想要的......

坚持 - 这很难看。这不是C ++应该如何编写的。无缘无故地进行如此多的动态分配。这也意味着当你完成它时你必须记住delete一切 - 这也很难看。如果您不依赖于动态分配,这一切都可以变得更加容易。您可以创建一个多维数组而不是使用指针,并且您的生活已经变得更加容易了:

SomeClass* world[20][20];

所以现在world是指向SomeClass的20 x 20指针数组。你实际上得到在内存中。你不只是像以前那样获得指针。你得到一个完整的多维指针数组!幸运的你。

现在,你可以通过根本不使用指针来使它变得更好。目前,您需要动态分配SomeClass个对象并在数组中指向它们。但为什么不使用SomeClass数组?

SomeClass world[20][20];

现在你有一个SomeClass个对象的多维数组!人生并没有比这更好。您不必手动分配或删除任何内容。你在内存中给出了一个完整的多维数组,其中每个元素都已经是SomeClass对象,可以为你的服务做好准备。

我们甚至可以通过使用标准库中的容器来进一步提高安全性。如果您使用的是C ++ 03,则可以使用std::vector<std::vector<SomeObject> >,但这可能有点过分。但是,C ++ 11引入了一种使用传统数组巧妙地替换的类型,使其更加安全:std::array。您可以像这样使用它:

std::array<std::array<SomeObject, 20>, 20> world;

答案 1 :(得分:3)

您获得的实际错误来自使用尚未初始化的指针。 0xcdcdcdcd是Visual Studio中内存的“填充模式”。选择它是为了让你在使用它时“注意到”它会导致内存访问冲突。

如何解决它:谷歌“如何在c ++中分配两个dimenisonal数组”。

答案 2 :(得分:3)

只需将20x20的数组作为成员(或在堆栈上)分配,然后填充它:

SomeClass *world[20][20];
for ...

如果大小不是常数,则需要逐行分配。