无法访问在指针数组中创建的对象
Cannot access objects created in array of pointers
我在访问指针数组中创建的对象时遇到问题。我有一些测试代码显示正在创建对象,但在我的ShowCluster()
函数中,它挂在通过第二级循环的第一次迭代上。
我认为我对它进行编码的方式是,我有一个Node**对象,它本质上变成了一个2d数组。由于我使用的是new
运算符,所以我不必担心函数内部的作用域。
关于为什么我不能显示我创建的这些对象的内容的任何想法。这只是我想用来帮助我理解指针的玩具代码。
主要.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++;
}
节点.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_ */
无论您在Default2dNodeArray
函数中对Node** myCluster
变量做什么,它在主函数中都不可见,因为您按值传入myCluster
。因此main
中的myNodeArray
不会被修改。如果您想修改它,可以从函数中返回新变量,也可以将函数签名更改为
void Default2dNodeArray(Node**& myCluster, int height, int width, int vecLength)
(注意第一个参数中的引用)。使用三指针也是可能的,但我认为修改传递的变量的意图可以通过引用更好地表达,尤其是因为您已经在处理双指针了。此外,它还保留了代码的其余部分。
您正试图创建一个指向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..
最后一条建议:尽管这只是一个测试,但记住要释放所有分配的内存,否则会泄露内存!
- 使用基类指针创建对象时,缺少派生类析构函数
- 如何创建对象函数指针C++映射?
- C++创建对象数组
- 在 C++ 的 Switch Case 中创建对象后对对象调用方法
- 如何获取在 main() 函数中构造的类的创建对象?
- 基于文件中的条目创建对象
- 错误:创建对象后无法分配区域
- C++ 通过输入创建对象
- 堆还是堆栈用于创建对象?
- 使用 C++ 创建对象数组
- 使用unique_ptr创建对象
- C++递归地在类构造函数中创建对象
- 通过向构造函数其他对象引用页面来创建对象
- ReactiveX (rx) - 在对象上应用可观察对象,而不是在可观察对象中创建对象
- 如何在OSX上正确创建C++对象文件(.o)
- 编译器是否会创建vtable,而不考虑在c++中创建对象
- 创建对象并防止被破坏
- 在C++中,友元类可以从友元类创建对象吗
- 只在堆中创建C++对象
- 创建用户定义的复制构造函数时无法创建对象