0

很长一段时间后,我在做 C++,有些事情困扰着我。我在这里发现了类似的问题,但没有一个能解决我的问题。那么,有什么关系呢?

我有

SomeClass*** world;

它提供了指向 SomeClass 对象的指针矩阵。

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

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

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

提前致谢!

4

3 回答 3

4

我认为了解声明变量时得到的结果非常重要。如在内存中实际创建的内容。

那么让我们来看看SomeClass*** world;。这对有什么好处?它会给你一个指针矩阵SomeClass吗?不,它没有。事实上,您可能会惊讶地发现,这只会为您带来一件事而且只有一件事 - 一个指针。是的,没错,只有一个指针。您已经定义了这个world变量,它是一个指针,这就是您从中得到的全部。那个单指针。

然后,该指针应用于指向其他指针,这些指针又指向指向 的指针SomeClass。但是,它指向的那些东西还不存在。因此,当您迭代最多 20 次并做i时,您正在尝试访问一个根本不存在的指针矩阵。jworld[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是一个 20 x 20 的指针数组SomeClass。你实际上在记忆中得到了它。你不会像以前那样得到一个指针。你得到一个完整的多维指针数组!幸运的你。

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

SomeClass world[20][20];

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

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

std::array<std::array<SomeObject, 20>, 20> world;
于 2012-12-22T11:42:41.783 回答
3

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

如何解决:谷歌“如何在 C++ 中分配两个维度数组”。

于 2012-12-22T11:07:55.843 回答
3

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

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

如果大小不固定,则需要逐行分配。

于 2012-12-22T11:12:58.377 回答