使用 new 实例化的结构上的未初始化内存警告

Uninitialized memory warning on structs instantiated with new

所以我有一个节点结构

struct Node
{
    int x = 0;
};

我做了 20 Node*s。我的理解是 Node** 是指向数组开头的指针,该数组包含指向 Nodes.

的指针
constexpr int mazeSize = 20;
Node** testMaze = new Node * [mazeSize];

在此之后,当我尝试用它做任何事情时,我开始收到警告和错误。示例:

testMaze[0]->position.x == 0; //->Using uninitialized memory `*testMaze` and 

我从这个错误中了解到:*testMaze 正在取消引用指针数组,这意味着它指的是该数组中的第一个 Node 对象。如果是这种情况,我将如何初始化它?如果我只是这样创建 Node*

Node* node = new Node;
node->x = 0; 

它工作正常而且不需要初始化它,那么为什么不用我这样做呢?我也不明白如何初始化结构。

另一个例子:

testMaze[0]->x == testMaze[1]->x //->Runtime error: Access violation reading error
testMaze[0]->x = 0; //->Runtime error: Access violation writing error

我该如何解决这些问题?谢谢。

永远记住指针类型是独立的具体类型,有自己的类型和大小。指向 T T* 的指针基本上可以归结为一小块内存,用于将地址存储到另一个内存区域,(希望)包含某种类型的实例 T.

Node** testMaze = new Node * [mazeSize];

您正在分配 maxSize 指针大小 类型 Node*sizeof(Node*) 元素的数组(在现代平台上通常为 4或 8 个字节,具体取决于您的可执行文件是在 32 位还是 64 位模式下 运行。

这些新创建的指针没有被初始化,因此指向无效地址,除非你也零初始化数组:

Node** testMaze = new Node * [mazeSize] {};
assert (testMaze[0] == nullptr); // holds true

为了获得 NodemaxSize 个实例,您必须创建 NodemaxSize 个实例:

Node** testMaze = new Node* [mazeSize];
for (std::ptrdiff_t i {}; i < maxSize; ++i) {
    testMaze[i] = new Node { /* insert parameters here */ };
}

鉴于您使用的是 constexpr,我推断您所针对的 C++ 修订版是 C++11 或更新版本。在这种情况下,您应该意识到 operator newoperator new[] 在编写现代 C++ 时几乎总是错误的选择,因为它们只有 returns 指针,您必须管理其所有权和生命周期手工。

你绝对应该开始使用 STL 容器,例如 std::vectorstd::array,它们更易于使用,并且可以避免你很多不必要的痛苦。如果你非要用new,至少看一下std::unique_ptr,里面包裹了一个指针或者C数组,一出就自动调用delete或者delete[]范围。

问题:

    constexpr int mazeSize = 20;
    Node** testMaze = new Node *[mazeSize]; //this makes 20 pointers, but the pointers dont point to anything
    testMaze[0]->position.x == 0; //undefined, as testMaze's pointers do not point to anything

这是有效的,因为你创建了一个新的 node,而不是一个指向 node.

的新指针
Node * node = new Node;
node->x = 0;

至于这个:

    testMaze[0]->x == testMaze[1]->x; //This is an undefined pointer, it doesn't point to anything, and you are trying to access it, so UNDEFINED behavior
    testMaze[0]->x = 0; //This is a undefined pointer, it doesn't point to anything, and you are trying to access it, so UNDEFINED behavior
}

我会这样做:

Node** Make(int size) {
    Node** temp = new Node * [size];
    Node* pool = new Node[size];
    for (int i = 0; i < size; ++i) {
        temp[i] = &pool[i];
    }
}

这使您的指针数组,使您的指针指向指向实际值的实际指针。

此外,不要忘记 delete[] 你的 Node**Node*,否则你会发生内存泄漏!