我试图以这种方式分配内存:
主要
X** a;
func(a);
FUNC:
func(X** a){
int size = 5;
X* array = (X*)malloc(5*sizeof(X));
//some writing to the array..
a = &array;
}
如果使用调试器,我看到当我在函数func
时一切正常=我可以写入数组并且a
确实指向数组但是我回到了main我发生了一些变化,我无法通过a
访问数组(在调试器上它写的内容如下:Target request failed: Cannot access memory at address 0x909090c3
等等。)
我的错误在哪里?
注意:如果尝试在 main 部分中访问(例如打印)数组,它会编译但运行时出现问题。
感谢。
答案 0 :(得分:7)
你必须改变这样的主体:
X* a; // create an uninitialized pointer
func(&a); // pass the address of that pointer to the function
在你的功能中,执行此操作:
void func(X** a){
int size = 5;
X* array = (X*)malloc(5*sizeof(X));
//some writing to the array..
*a = array; // change the value of the pointer to point to the array
// you allocated
}
请注意,在C ++中,可以使用std::vector<X>
:
std::vector<X> func() {
std::vector<X> buffer(5);
// do stuff with buffer
return buffer;
}
std::vector<X> foo = func();
这将在函数内部创建一个新的vector
,并将该向量的副本返回给调用者。请注意,副本将被优化掉。
答案 1 :(得分:3)
您正在更改变量a
的本地副本,它不会传播到函数外部(即调用范围)。解决问题的最简单方法是通过引用传递a
,但您也可以使用指针传递它并解除引用函数内部的指针。
见下面的例子。
void func (X*& a) {
X* array = (X*) malloc (5*sizeof(X));
a = array;
}
...
X* a;
func (a);
下面一行中的&符号表示a正在通过引用传递,即。在函数内部更改它将使更改传播到调用者使用的参数。
void func (X*& a) {
如果您对指针缺乏经验,这很难理解,但我们会让func
将指针指向作为参数并传入地址来自main的变量a
。
在解除引用指针指针后,我们可以安全地存储我们想要的信息。
void func (X** pointer_to_a) {
X* array = (X*) malloc (5*sizeof(X));
*pointer_to_a = array;
}
...
X * a;
func (&a); // pass in address of a
由于您正在编写C ++(通过问题标题和标记说明),因此您不应使用std::malloc
,而应使用operator new
。
答案 2 :(得分:1)
如果要将a
的目标设置为array
的值,则将本地指针a
设置为本地指针array
的地址:
*a = array;
并将其命名为
X * a;
func(&a);
返回指针(即X * func()
)会不那么容易混淆。
另外,你已经标记了这个C ++而不是C,所以你不应该使用malloc
;使用标准容器,或者如果它们不适合你,使用new
进行分配,并使用智能指针管理内存。
答案 3 :(得分:1)
在main
中,a
是指向指针的指针。这意味着必须存在两件事:内存块和指向它的指针。然后a
可以指向该指针。在您的尝试中,该中间指针正在func
的堆栈上分配,当func
返回时,它被销毁,因此不会起作用。
你可以这样做:
X* pa;
X** a = &pa;
func(a);
func(X** a){
int size = 5;
X* array = (X*)malloc(5*sizeof(X));
//some writing to the array..
*a = array;
}
答案 4 :(得分:0)
考虑一下: a =&amp;数组; array是在堆上分配的局部变量,&amp;数组在其范围结束时将是垃圾(函数体)。