我知道这有一个非常简单的解释,但我被宠坏了一段时间不必使用指针。为什么我不能通过将指针传递给函数来初始化数组?
为什么我不能做这样的事情在C++
int* b;
foo(b);
和初始化通过阵列...
void Something::foo(int* a)
{
a = new int[4];
}
调用foo(B),B仍然是空之后。为什么是这样?
我知道这有一个非常简单的解释,但我被宠坏了一段时间不必使用指针。为什么我不能通过将指针传递给函数来初始化数组?
为什么我不能做这样的事情在C++
int* b;
foo(b);
和初始化通过阵列...
void Something::foo(int* a)
{
a = new int[4];
}
调用foo(B),B仍然是空之后。为什么是这样?
通过值将指针传递给函数。实质上,这意味着指针值(但不是指针!)被复制。你修改的只是原始指针的副本。
有两个解决方案,无论是使用间接的附加层:
要么使用的引用:
void f(int*& a) {
a = new int[4];
}
或者你在一个指针到指针传递(以下传统的输出参数如您的情况):
void f(int** pa) {
*pa = new int[4];
}
并调用函数li柯本:
f(&a);
就个人而言,我不喜欢这两种风格:参数是功能输入,输出应该是返回值进行处理。到目前为止,我还没有看到在C++中偏离这个规则的令人信服的理由。所以,我的建议是:改用下面的代码。
int* create_array() {
return new int[4];
}
您可以通过值将参数传递给foo。更改为
foo(int*& a)
您正在传递价值。
您需要通过按引用:
void Something::foo(int* &a)
{
a = new int[4];
}
也许是更清楚这样做:
int* Something::foo()
{
int* a = new int[4];
return a;
}
int* b = foo();
确保当你返回一个指针(或更新参考)由一种方法分配的内存,它清楚何时应该释放它以及由谁释放。
出于同样的原因,您不能通过传递值来初始化整数。
两点在这里提出:
1)
int* b;
这确实应该:
int* b = NULL;
这只是因为它是因为你下运行的空调试报告调试。编译下发布会给b一个随机指针。
2)
如果你传递一个指针的指针,那么你的功能应该能够分配内存:
int* b = NULL;
Something::foo(&b);
void Something::foo(int** a)
{
*a = new int[4];
}
你必须使用一个参考或做类似:
int* b;
foo(b);
void Something::foo(int** a)
{
*a = new int[4];
}
(这是老派的C做法,我认为参考比较好)
因为您将NULL传递给该函数。你需要的是像(指针的指针):
int* b;
foo(b);
void Something::foo(int** a)
{
*a = new int[4];
}
指针是一个整数值(32位操作系统是32位整数),这是内存地址。您将整数值传递给函数。通过通过将值推入堆栈。然后,您从堆栈中删除该值,并通过为其分配一些内存来更改该值。然后退出该功能并删除堆栈帧。该堆栈帧中的任何值都将被删除,包括您新分配的内存地址。
你想要做的是传递一个指针指针。
int* b;
foo(&b);
和
void Something::foo(int** a)
{
*a = new int[4];
}
在这里,您声明湾它是一个指向内存位置的整数值。你传入该整数值的地址。即ANOTHER指向内存位置的整数值,该位置包含指向内存位置的整数值。现在在foo函数 中,您将内存分配给您指向的指向另一个内存位置的地址。然后当你退出函数时,堆栈展开并且指针指针消失。但是,您的原始整数值(即指针)仍然保留您刚创建的值,而您的调用是新的。
+1用于良好的低级解释。 – 2009-08-11 14:06:45
为什么你会在C++(也许在C)中写'f(int ** pa)'。现在你需要检查NULL。你可以重新安排,以便更安全的技术在顶部(并添加NULL检查)。 – 2009-08-11 16:15:13
@Martin:'NULL'检查根本没有帮助,因为你在C++中真正需要的是一个指针合法性检查 - 它不存在。所以不行,代码是完整的,虽然很脆弱,但是调用者的责任是确保指针是正确的,我同意这不是你想写的代码。 *但是,实际上有些人会看到这种风格的好处,因为它在调用者的网站上显而易见*该函数修改了参数的值。这在参考文献中并不明显。就我个人而言,我不同意 - 但是,我永远不会使用'out'参数。 – 2009-08-11 17:40:52