我最近遇到了一个问题,我想不出一个好的解决方法。我正在使用案例结构来尝试将属性设置为将传递给对象构造函数的“字符”。
示例:
//note this is inside a function with a return type of int*
int selection;
cin >> selection;
int * iPtr;
switch(selection){
case 1:{
int anArray[6] = {8,5,2,4,250,100} // str, dex, int, luck, hp, mp
iPtr = anArray;
return iPtr;
}
//more cases and such below
我遇到的问题是,当我返回指针时,它似乎充满了大量的垃圾,而不是信息,而不是我期望它持有的信息。那是因为数组在范围的末尾被销毁了吗?如果是这样我应该怎样做才能使我能够解决这个问题(获取一个包含我想要的值的指针)。
谢谢!
答案 0 :(得分:6)
是 - 在堆栈上声明了anArray。当函数退出时,它的堆栈帧被回收,因此引用该内存不再有效。如果您希望数组保持不变,请将其分配到堆上:
int* anArray = new int[6]; // and initialize
return anArray;
请记住稍后使用相应的delete[]
来清理它。
修改强>
您应该更喜欢使用能够自动管理资源的东西,例如Praetorian的答案,这样您就不会意外泄漏内存。
答案 1 :(得分:4)
是的,您声明的数组确实是函数的本地数组,并且在函数退出后不再存在。您可以使用new
动态分配数组,然后让调用者delete[]
成为内存(但不要执行此操作!),或修改函数以返回std::unique_ptr
而不是原始数据指针。
unique_ptr<int[]> anArray (new int[6]);
// do initialization
return anArray;
现在,调用者不必担心释放函数分配的内存。
修改强>
有几种不同的方法可以执行unique_ptr
的初始化。
anArray[0] = 8;
anArray[1] = 5;
// etc ...
OR
int init[6] = {8,5,2,4,250,100};
std::copy( &init[0], &init[0] + 6, &anArray[0] );
答案 2 :(得分:3)
是的,这是因为程序运行时会覆盖本地数组。您可以在方法中声明数组static(这对于像这样的固定数组来说是一个好主意),在全局范围内声明它,或者分配一个返回new
的数组。最后一个替代方案使您有机会为每个调用返回一个不同的数组,但请记住在使用后释放数组。
答案 3 :(得分:1)
在C ++中,最好的答案是不返回指针。相反,使用适当的对象而不是C数组或手动分配内存并返回此对象:
std::vector<int> f() {
std::vector<int> array;
// fill array
return array;
}
使用new int[x]
(或其他)在现代C ++代码中确实已经被弃用,并且在非常特殊的情况下才被认为是可接受的。如果您在普通代码中使用它,这是一个非常明显的改进之处。手动管理内存的其他用途也是如此。 C ++的全部优势在于,不必须管理自己的内存,从而避免了大量难以追踪的错误。
答案 4 :(得分:0)
是的,这是因为您创建的数组是在堆栈上创建的,当您返回时,您所在的堆栈部分将被覆盖(可能是通过调试过程)。
为避免这种情况,你可以写
int* anArray = new int[6];
// fill the array
return anArray;
在这种情况下,您还必须在完成后删除返回的结果,例如
int* dataArray = getTheArray();
// Use the dataArray
delete [] dataArray;
答案 5 :(得分:0)
在堆上分配数组
int* anArray = new int[6];
您必须手动删除它:
delete[] iPtr;