C++ 无法访问在指针数组中创建的对象

C++ 无法访问在指针数组中创建的对象,c++,arrays,pointers,multidimensional-array,C++,Arrays,Pointers,Multidimensional Array,我在访问指针数组中创建的对象时遇到问题。我有一些测试代码显示正在创建对象,但在我的ShowCluster()函数中,它挂起在第二级循环的第一次迭代中 我认为我对它进行编码的方式是,我有一个节点**对象,它本质上变成了一个2d数组。因为我使用的是new操作符,所以我不必担心函数内部的作用域 关于我为什么不能显示我创建的这些对象的内容的任何想法。这只是我想用来帮助我理解指针的玩具代码 Main.cpp #include <iostream> #include "Node.h" void

我在访问指针数组中创建的对象时遇到问题。我有一些测试代码显示正在创建对象,但在我的
ShowCluster()
函数中,它挂起在第二级循环的第一次迭代中

我认为我对它进行编码的方式是,我有一个节点**对象,它本质上变成了一个2d数组。因为我使用的是
new
操作符,所以我不必担心函数内部的作用域

关于我为什么不能显示我创建的这些对象的内容的任何想法。这只是我想用来帮助我理解指针的玩具代码

Main.cpp

#include <iostream>
#include "Node.h"

void Test(std::string message){
    static int testNumber = 0;
    std::cout << "[+] Test: " << testNumber << " : " << message << std::endl;
    testNumber++;
}

void Default2dNodeArray(Node** myCluster, int height, int width, int vecLength){
    Test("Start of array creation.");

    myCluster = new Node*[height];

    for(int i=0; i<height; i++){
        myCluster[i] = new Node[width];
    }

    Test("End of array creation.");

}

void ShowCluster(Node **myCluster, int height, int width){
    Test("Start of Display array.");
    for(int i=0; i<height; i++){
        Test("Outer for loop");
        for(int j=0; j<width; j++){
            Test("Inner for loop");
            std::cout << myCluster[i][j].myNodeString << " : " << myCluster[i][j].myNodeInt << std::endl;
        }
    }
    Test("End of Display array.");

}


int main(){

    int myHeight = 5;
    int myWidth =8;
    int myVecLength = 4;
    Node** myNodeArray;

    std::cout << "Starting pointer test" << std::endl;

    Test("In main.");
    Default2dNodeArray(myNodeArray, myHeight, myWidth, myVecLength);
    Test("In main.");
    ShowCluster(myNodeArray, myHeight, myWidth);
    Test("In main.");

    std::cout << "Ending pointer test" << std::endl;

    return 1;
}
#包括
#包括“Node.h”
无效测试(std::字符串消息){
静态int testNumber=0;

std::cout无论您对
default2dnoderray
函数中的
Node**myCluster
变量做什么,它在主函数中都不可见,因为您按值传入
myCluster
。因此
main
中的
mynoderray
将不会被修改。如果要修改它,请返回新的变量可从函数中删除,或将函数签名更改为

void Default2dNodeArray(Node**& myCluster, int height, int width, int vecLength)

(注意第一个参数中的引用)。使用三重指针也是可能的,但我认为修改传递的变量的意图最好通过引用来表达,特别是因为您已经在这里处理双指针。此外,它使代码的其余部分保持不变。

您正在尝试创建一个指向
节点
对象的指针数组s并初始化每个指向堆上分配的
节点
对象的指针,并将其作为参数传递

将指针传递给函数可以通过值来完成(即指针被复制,您可以通过取消引用来访问指向它的内存,但不能更改原始指针指向的值),方法是获取其地址并将其传递给函数,例如

Node *ptr = 0x10;
function(&ptr);    

void function(Node** ptr_to_ptr) {
    (*ptr_to_ptr) = 0x20; // This will modify ptr
}
或通过引用(也将修改原始指针值)

在您的情况下,由于需要一个双指针来保存指向
节点
对象的指针数组,并且您试图通过获取其地址来传递它,因此最终将使用三个指针:

void Default2dNodeArray(Node*** myCluster, int height, int width, int vecLength) {
    Test("Start of array creation.");

    // Dereference to access the original double pointer value
    *myCluster = new Node*[height];

    for (int i = 0; i<height; i++){
        (*myCluster)[i] = new Node[width];
    }
    Test("End of array creation.");
}

void ShowCluster(Node*** myCluster, int height, int width) {
    Test("Start of Display array.");
    for (int i = 0; i<height; i++){
        Test("Outer for loop");
        for (int j = 0; j<width; j++){
            Test("Inner for loop");
            std::cout << (*myCluster)[i][j].myNodeString << std::endl;
        }
    }
    Test("End of Display array.");
}

int main(){
    int myHeight = 5;
    int myWidth = 8;
    int myVecLength = 4;
    Node** myNodeArray; // Double pointer

    std::cout << "Starting pointer test" << std::endl;

    Test("In main.");
    Default2dNodeArray(&myNodeArray, myHeight, myWidth, myVecLength);
    Test("In main.");
    ShowCluster(&myNodeArray, myHeight, myWidth);
    Test("In main.");

    std::cout << "Ending pointer test" << std::endl;
    return 1;
}
void Default2dNodeArray(Node**& myCluster, int height, int width, int vecLength)
// etc..

最后一条建议:尽管这只是一个测试,但请记住释放所有分配的内存,否则最终会导致内存泄漏!

因此,如果我没有使用“新”运算符我可以按原样传递指针,然后更改对象的成员,同时在退出函数时保留这些更改?即使只传递值,
myCluster
级别以下的所有内容都会保留。
myCluster
指向指针数组的第一个元素。该ar中的每个指针射线指向
节点
对象数组的第一个元素。可以更改指针数组中的指针指向的对象,也可以更改它们指向的数组中的
节点
对象。但是(如果没有引用),不能在函数外更改
myCluster
的值(即,在您的情况下,
mynoderray
mynoderray
在main stays范围内,未初始化并指向垃圾。
mynoderray
必须指向有效的对象(至少指向指针数组,即
Node*
),即使未初始化,如果您坚持按值将其传递给函数,因为您无法更改它所指向的内容。但是,我认为以这种方式分割分配工作是个坏主意。如果不使用引用,更一致的想法是不从主函数传递
mynoderray
,而是使
default2dnoderray
返回一个
节点**
,该节点指向一个新(且完全)分配的数组。然后用该返回值初始化
myNodeArray
Node *ptr = 0x10;
function(ptr);    

void function(Node*& ref_to_ptr) {
    ref_to_ptr = 0x20; // This will modify ptr
}
void Default2dNodeArray(Node*** myCluster, int height, int width, int vecLength) {
    Test("Start of array creation.");

    // Dereference to access the original double pointer value
    *myCluster = new Node*[height];

    for (int i = 0; i<height; i++){
        (*myCluster)[i] = new Node[width];
    }
    Test("End of array creation.");
}

void ShowCluster(Node*** myCluster, int height, int width) {
    Test("Start of Display array.");
    for (int i = 0; i<height; i++){
        Test("Outer for loop");
        for (int j = 0; j<width; j++){
            Test("Inner for loop");
            std::cout << (*myCluster)[i][j].myNodeString << std::endl;
        }
    }
    Test("End of Display array.");
}

int main(){
    int myHeight = 5;
    int myWidth = 8;
    int myVecLength = 4;
    Node** myNodeArray; // Double pointer

    std::cout << "Starting pointer test" << std::endl;

    Test("In main.");
    Default2dNodeArray(&myNodeArray, myHeight, myWidth, myVecLength);
    Test("In main.");
    ShowCluster(&myNodeArray, myHeight, myWidth);
    Test("In main.");

    std::cout << "Ending pointer test" << std::endl;
    return 1;
}
void Default2dNodeArray(Node**& myCluster, int height, int width, int vecLength)
// etc..