简体   繁体   English

C ++用数字填充数组,然后返回指向它的指针

[英]C++ filling an array with numbers then returning a pointer to it

Ive been faced with a problem recently that I can't think of a good way to solve. 我最近遇到了一个我想不出解决办法的问题。 I'm using a case structure to attempt to set attributes to a "character" that will be passed to an object constructor. 我正在使用一种案例结构来尝试将属性设置为将传递给对象构造函数的“字符”。

Example: 例:

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

The issue that I'm having is that when I return my pointer it seems to be filled with a good amount of junk, rather than the information, rather than the information that I would be expecting it to hold. 我遇到的问题是,当我返回指针时,它似乎充满了大量的垃圾,而不是信息,而不是我期望它保存的信息。 Is that because the array gets destroyed at the end of the scope? 那是因为数组在作用域末尾被销毁了吗? If so what should I do to make this work out how I'm hoping for it to (getting a pointer with the values that I want). 如果是这样,我应该怎么做才能使它达到我的期望(获取具有所需值的指针)。

Thanks! 谢谢!

Yes - anArray is declared on the stack. 是的-在堆栈上声明了anArray。 When the function exits, its stack frame is reclaimed, so it's no longer valid to refer to that memory. 当函数退出时,将回收其堆栈框架,因此引用该内存不再有效。 If you want the array to persist, allocate it on the heap instead: 如果要保留数组,请在堆上分配它:

int* anArray = new int[6]; // and initialize
return anArray;

Just remember to clean it up later at some point with the corresonding delete[] . 只需记住稍后使用相应的delete[]清理它delete[]

EDIT 编辑

You should prefer to use something that automatically manages resources for you, like in Praetorian's answer, so that you don't accidentally leak memory. 您应该喜欢使用可以自动为您管理资源的工具(例如Praetorian的回答),以免意外泄漏内存。

Yes, the array you've declared is indeed local to the function and no longer exists once the function exits. 是的,您声明的数组确实是函数的局部数组,函数退出后将不再存在。 You can dynamically allocate an array using new and then have the caller delete[] the memory (but don't do this!), or modify your function to return an std::unique_ptr instead of a raw pointer. 您可以使用new动态分配一个数组,然后让调用方delete[]内存(但不要这样做!),或修改函数以返回std::unique_ptr而不是原始指针。

unique_ptr<int[]> anArray (new int[6]);
// do initialization
return anArray;

Now, the caller doesn't have to worry about freeing memory allocated by the function. 现在,调用者不必担心释放函数分配的内存。

EDIT: 编辑:

There are a couple of different ways to perform initialization of the unique_ptr . 有两种不同的方法可以执行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] );

Yes, it's because the local array is overwritten as the program runs. 是的,这是因为程序运行时本地数组被覆盖了。 You can either declare the array static in the method (which would be a good idea for a fixed array like this), declare it at global scope, or allocate an array with new to return. 您可以在方法中声明静态数组(对于像这样的固定数组来说是个好主意),可以在全局范围内声明它,也可以分配一个带有new的数组以返回。 The last alternative gives you the opportunity to have a different array returned for each call, but remember to deallocate the arrays after use. 最后一种选择使您有机会为每个调用返回一个不同的数组,但是请记住在使用后取消分配数组。

In C++, the best answer is not to return a pointer . 在C ++中,最好的答案是不返回指针 Instead, use a proper object instead of a C array or manually allocated memory and return this object: 相反,请使用适当的对象而不是C数组或手动分配的内存并返回此对象:

std::vector<int> f() {
    std::vector<int> array;
    // fill array

    return array;
}

Using new int[x] (or whatever) is really, really deprecated in modern C++ code and is only deemed acceptable under very special circumstances. 在现代C ++代码中,确实不建议使用new int[x] (或其他方法),并且仅在非常特殊的情况下才认为可以接受。 If you use it in normal code, this is a very obvious place for improvement. 如果在普通代码中使用它,那么这是一个非常明显的改进之处。 The same goes for other uses of manually managed memory. 手动管理的内存的其他用途也是如此。 The whole strength of C++ lies in the fact that you don't have to manage your own memory, thus avoiding a multitude of hard to track bugs. C ++的全部优势在于您不必管理自己的内存,从而避免了许多难以跟踪的错误。

Yes, it is because the array you created is created on the stack, and when you return, the part of the stack that you were at is overwritten (presumably by a debug process). 是的,这是因为您创建的数组是在堆栈上创建的,并且当您返回时,您所在的堆栈部分将被覆盖(可能是通过调试过程)。

To avoid this, you would write 为了避免这种情况,您可以编写

int* anArray = new int[6];
// fill the array
return anArray;

In this case, you will also have to delete the returned result when you are finished with it, such as in 在这种情况下,您还必须在完成后删除返回的结果,例如

int* dataArray = getTheArray();
// Use the dataArray
delete [] dataArray;

Allocate array on the heap 在堆上分配数组

int* anArray = new int[6];

You will have to delete it manually: 您将必须手动删除它:

delete[] iPtr;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM