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

时间:2014-11-03 18:20:40

标签: c++ arrays pointers multidimensional-array

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

我认为我编码的方式是我有一个Node **对象,它本质上变成了一个二维数组。由于我使用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.cpp

#include "Node.h"
#include <stdlib.h>
#include <stdio.h>
#include <sstream>
#include <iostream>


int Node::globalCounter = 0;

Node::Node(){

    std::cout << "Node created." << std::endl;

    std::stringstream ss;
    ss << "Default: " << globalCounter;

    myNodeString = ss.str();;
    myNodeInt = globalCounter;
    myVecLength = new int[3];

    globalCounter++;

}

Node::Node(std::string myString, int myInt, int vecLength){
    myNodeString = "Non-Default:" + myString;
    myNodeInt = globalCounter;

    myVecLength = new int[vecLength];
    globalCounter++;
}

Node.h

#ifndef NODE_H_
#define NODE_H_

#include <string>

class Node {

public:

    static int globalCounter;
    std::string myNodeString;
    int myNodeInt;
    int* myVecLength;

    Node();
    Node(std::string, int, int);


};

#endif /* NODE_H_ */

2 个答案:

答案 0 :(得分:1)

无论您对Node** myCluster函数中的Default2dNodeArray变量做什么,它都不会在您的主函数中显示,因为您按值传递myCluster。因此,myNodeArray中的main将不会被修改。如果要修改它,请从函数返回新变量,或将函数签名更改为

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

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

答案 1 :(得分:0)

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

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

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

void function(Node** ptr_to_ptr) {
    (*ptr_to_ptr) = 0x20; // This will modify ptr
}

或通过引用(也将修改原始指针值)

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

void function(Node*& ref_to_ptr) {
    ref_to_ptr = 0x20; // This will modify ptr
}

在你的情况下,因为需要一个双指针来保存指向Node对象的指针数组,你试图通过获取它的地址传递它,你是最终会使用三重指针:

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..

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