所以,我有这个数组。需要在此函数范围之外访问它。我一直把它的指针打成一对放入双端队列的指针。但是一旦我超出范围,本地堆栈就会消失,数组无效,我只是有一个无用的指针,对吗?
所以我试图把这个数组放到范围超越堆上,它将一直存在,直到我以后删除它。但是我在解决这个问题上遇到了问题。现在g ++正在咳嗽从'int'到'int *'的无效转换错误。
void randomFunction(int x, int y, int width, int height)
{
int **blah[4] = {x, y, width, height};
std::pair <foobar*, int* > tempPair (foobar1, blah);
randomDeque.push_front(tempPair);
}
我也试过像这样初始化它:
int *blah[4] = new int[4];
...并且它表示必须使用括号括起的初始化程序初始化数组。
我真的不习惯使用指针。我做错了什么?
答案 0 :(得分:2)
有两个问题。首先,你确实对指针/数组感到困惑:
int a[4]; // this is an array of 4 integers, a is the name of the array
int *a[4]; // This is an array of 4 *pointers* to int
所以你的宣言:
int **blah[4];
定义一个指向指针数组的4个指针的数组。也许你对以下事实感到困惑(我知道我是在学习C的时候)。如果您声明变量:
int *a;
这是指向整数的指针的声明。但是如果你有一个变量a是一个指针,你可以通过使用* a来获得它所指向的东西(这里是一个整数):
*a = 1; // a is a pointer (i.e. an address), *a is the value pointed to by a.
因此声明中的*用于声明指针,但* in语句用于表示值。
但是你的第二个问题与指针本身无关。它是关于资源管理(内存是一个,但文件,锁定是其他)。当它超出范围时,在堆栈上分配的任何内容都不再存在。在纯C中,您只有一个解决方案:使用malloc在堆上分配,并确保之后可以释放。所以你会做类似的事情:
// foo is a struct
foo *init_foo()
{
foo* tmp;
tmp = malloc(sizeof(*tmp));
// initialize tmp
return tmp;
}
然后,你将用另一个功能清理它:
foo *a;
a = init_foo();
// do stuff
clean_foo(a);
示例:FILE *句柄和fopen / fclose(除了分配东西之外,还有一些与操作系统相关的东西来处理文件)。另一个解决方案是使用alloca,它不是标准的C,但是受到许多工具链的支持。
在C ++中,您可以使用智能指针,它使用例如引用计数来进行资源管理。我对C ++不太熟悉,我相信人们会加入这个部分。引用计数的想法是它仍然提供了自动指针的一些优点(你不必自己调用delete,这对于非平凡的项目非常容易出错),但不是纯粹基于范围的。一个基于引用计数的智能指针是boost中的shared_ptr。
答案 1 :(得分:1)
整个概念对我来说很奇怪。如果在堆栈上声明数组,它将不存在于函数范围之外。如果你使用'new'分配它 - 确保你有时'删除'它,否则它是内存泄漏! 带有'new'的正确代码是:
int *blah = new int[4];
...
// don't forget to:
delete [] blah;
答案 2 :(得分:1)
我不确定我是否做对了你想做的事情,但是如果你想要返回一个对randomFunction
返回后有效的int数组的引用,一个很好的方法是与Boost:
#include <boost/shared_ptr.hpp>
#include <vector>
boost::shared_ptr<std::vector<int> > randomFunction(int x, int y, int width, int height)
{
boost::shared_ptr<std::vector<int> > blahPtr(new std::vector<int>(4));
(*blahPtr)[0] = x;
(*blahPtr)[1] = y;
(*blahPtr)[2] = width;
(*blahPtr)[3] = height;
return blahPtr;
}
您不必记住delete
blahPtr
- 当它的所有副本超出范围时,Boost会自动删除您的std::vector
对象,以及C ++标准库将删除基础数组。
答案 3 :(得分:0)
看起来你想要一个4x4数组,在这种情况下你应该像这样创建它(从头顶开始的未经测试的代码):
int **blah = new int* [4];
for(int i = 0; i < 4; ++i)
{
*blah[i] = new int[4];
}
或者,您可以创建一维数组并将其视为二维数组:
int *blah = new int[16];
#define ELEM(x,y) w*4+h
blah[ELEM(1,1)] = 123;