简体   繁体   English

C ++ - 通过函数返回2D数组

[英]C++ - Returning a 2D array through function

I've looked around trying to figure out if I should return a 2D array in C++, but got mixed answers. 我环顾四周试图找出是否应该在C ++中返回一个二维数组,但得到的答案却很复杂。

Some of the answers say no because the data is local to the function and when it returns, the array points to "junk data" (as it can be overwritten at any time). 一些问题的答案说不 ,因为数据是本地的功能,当它返回时,阵列指向“垃圾数据”(因为它可以在任何时间被覆盖)。 However, some said "yes, return it like a normal array." 但是,有些人说“是的,就像普通数组一样返回它”。

So, to my dilemma: 所以,我的困境:

I have a 2D array that holds pointers to Tile objects 我有一个2D数组,其中包含指向Tile对象的指针

Tile* map[128][128];

Should I return the array in a function? 我应该在函数中返回数组吗? Why or why not? 为什么或者为什么不? If the answer is yes, how would I do that? 如果答案是肯定的,我该怎么做?

EDIT: I was unclear. 编辑:我不清楚。 I want to make a getter method to return the map variable and be able to use the pointers in the array in another function. 我想制作一个getter方法来返回map变量,并能够在另一个函数中使用数组中的指针。

You could do that... the problem is that your caller is now responsible for freeing the memory. 你可以这样做......问题是你的调用者现在负责释放内存。 And he might not know how you allocated it. 他可能不知道你是如何分配它的。 Should he call free()? 他应该打电话给free()吗? delete[]? 删除[]? A free routine provided by the OS? 操作系统提供的免费例程? Or one provided by some other memory caching system in your app? 或者你的应用程序中的其他一些内存缓存系统提供了一个?

Two common ways around this are: 两种常见的方法是:

  • Have the caller allocate the memory and your function merely populates it 让调用者分配内存,你的函数只是填充它
  • Use a C++ array class; 使用C ++数组类; here you might have a std::vector containing a std::vector of Tile*. 在这里你可能有一个std :: vector包含一个Tile *的std :: vector。 This is great as it absolves you of manually dealing with the memory allocation/deallocation. 这很好,因为它使您无法手动处理内存分配/释放。

But then... who's going to free the Tile* instances? 但那么......谁将释放Tile *实例? And with what API? 用什么API? So perhaps you need a vector of vectors of Tile, rather than Tile*. 所以也许你需要一个Tile矢量矢量,而不是Tile *。

vector<vector<Tile>> map;

The 2 answers you are getting is due to the two different ways this is possible. 你得到的2个答案是由于两种不同的方式。

Stack based - local memory, deallocated and the pointer returned is invalid 基于堆栈 - 本地内存,解除分配并返回指针无效

typedef int *(*TileGrid)[128];
Tile* map[128][128];
....
TileGrid GetTiles(){
    return map;
}

Heap Allocated - allocated on heap and not deallocated after the function ends, up to caller of this function to deallocate - safe . 堆分配 - 在堆上分配而不是在函数结束后解除分配,直到此函数的调用者才能解除分配 - 安全

typedef int *(*TileGrid)[128];
TileGrid map = new Tile*[128][128];
....
TileGrid GetTiles(){
    return map;
}

Recommended - C++ way - array instead of vector since size is compile time constant (true C++ way would be to use std::unique_ptr<Tile> instead of Tile*, but 1 issue at a time. These containers automatically manage the memory for you, and std::array can be used as if it is a regular array. 推荐 - C ++方式 - 数组而不是向量,因为大小是编译时常量 (真正的C ++方式是使用std::unique_ptr<Tile>而不是Tile *,但一次只有1个问题。这些容器会自动为你管理内存和std :: array可以像使用常规数组一样使用。

typedef std::array<std::array<Tile*,128>,128> TileGrid;
TileGrid map ;
...
TileGrid& GetTiles(){
    return map;
}

Return by reference to prevent an expensive copy, and because the function is just a getter and the object maintains ownership of the map . 通过引用返回以防止昂贵的副本,并且因为该函数只是一个getter并且该对象保持了map所有权。

Edit: fixed for a getter function 编辑:修复了getter功能

C/C++ has two types of memory - stack and heap. C / C ++有两种类型的内存 - 堆栈和堆。 Usually variables are allocated on the stack which is temporary storage and is marked for re-use whenever you exit the current scope - like when you end a loop or return from a function. 通常,变量在堆栈上分配,这是临时存储,并且在退出当前作用域时标记为可重复使用 - 例如当您结束循环或从函数返回时。

When you use new it will allocate heap memory which will stay around until you use delete but you have to be careful that you match up all the new and delete calls so that you don't get a memory leak. 当你使用new ,它将分配堆内存,它会一直存在,直到你使用delete但你必须小心你匹配所有新的和删除调用,这样你就不会出现内存泄漏。 There are many strategies for managing this situation in C++. 在C ++中管理这种情况有很多策略。 You can google for 'memory management in C++' to learn more. 你可以谷歌搜索“用C ++进行内存管理”来了解更多信息。

In your simple case, I would recommend avoiding pointers but using an stl container to build your array of tiles. 在您的简单情况下,我建议避免指针,但使用stl容器来构建您的tile数组。 For example a std::vector like vector< vector<Tile> > map . 例如,std :: vector就像vector< vector<Tile> > map You can use the same square brackets syntax to access the map eg map[x][y] = Tile(); 您可以使用相同的方括号语法来访问地图,例如map[x][y] = Tile(); That way the memory allocation and management of the array is handled in the vector class. 这样,数组的内存分配和管理在vector类中处理。

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

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