我知道这有一个非常简单的解释,但是我已经被一段时间不必使用指针所破坏了。
为什么我不能在c ++中做这样的事情
int* b;
foo(b);
并通过...
初始化数组void Something::foo(int* a)
{
a = new int[4];
}
在调用foo(b)之后,b仍为null。这是为什么?
答案 0 :(得分:13)
指针按值传递给函数。从本质上讲,这意味着复制指针值(但不是指针!)。您修改的只是原始指针的副本。
有两种解决方案,都使用额外的间接层:
使用引用:
void f(int*& a) {
a = new int[4];
}
或者你传入一个指向指针的指针(在你的情况下不像传统参数那样常规):
void f(int** pa) {
*pa = new int[4];
}
并调用这样的函数:
f(&a);
就个人而言,我不喜欢两种风格:参数是函数输入,输出应该由返回值处理。到目前为止,我还没有看到在C ++中偏离此规则的令人信服的理由。所以,我的建议是:改用以下代码。
int* create_array() {
return new int[4];
}
答案 1 :(得分:6)
您可以通过值将参数传递给foo。改为
foo(int*& a)
答案 2 :(得分:4)
你是值得传递的。
您需要传递参考:
void Something::foo(int* &a)
{
a = new int[4];
}
这样做可能更清楚:
int* Something::foo()
{
int* a = new int[4];
return a;
}
int* b = foo();
确保当您将指针(或更新引用)返回到方法分配的内存时,可以清楚地说明它应该被释放的时间和人员。
答案 3 :(得分:2)
出于同样的原因,你不能通过传递值来初始化整数。
答案 4 :(得分:1)
要点两点:
1)
int* b;
这应该是:
int* b = NULL;
它只是在调试器中报告它是null,因为你在debug下运行。在发布时编译将给b一个随机指针。
2)
如果您将指针传递给指针,那么您的函数应该能够分配内存:
int* b = NULL;
Something::foo(&b);
void Something::foo(int** a)
{
*a = new int[4];
}
答案 5 :(得分:1)
指针是一个整数值(32位OS是32位整数),它是存储器地址。您将整数值传递给函数。通过将值推送到堆栈来进行传递。然后从堆栈中删除该值,并通过在其上分配一些内存来更改该值。然后退出该函数并删除堆栈帧。删除该堆栈帧中的任何值,包括新分配的内存地址。
你想要做的是传入一个指向指针的指针。
int* b;
foo(&b);
和
void Something::foo(int** a)
{
*a = new int[4];
}
在这里你宣布b。它是指向内存位置的整数值。您传入该整数值的地址。即另一个整数值,指向包含指向内存位置的整数值的内存位置。现在在foo函数里面 您将内存分配给指向另一个内存位置的地址。然后当你退出函数时,堆栈展开,指向指针的指针消失。但是,您的原始整数值(即指针)仍保留您刚刚调用new时创建的值。
答案 6 :(得分:0)
您必须使用引用或执行以下操作:
int* b;
foo(b);
void Something::foo(int** a)
{
*a = new int[4];
}
(这是老派的C方式,我认为参考更好)
答案 7 :(得分:0)
因为您将NULL传递给函数。你需要的是(指针指针):
int* b;
foo(b);
void Something::foo(int** a)
{
*a = new int[4];
}