当我试图给NULL指针赋值时,我得到分段错误。下面是代码:
#include <iostream>
using namespace std;
struct test {
int val;
};
void insert(test* t, int value) {
test* x = (test*)malloc(sizeof(test*));
x->val = value;
t = x;
}
int main() {
test* a = NULL;
insert(a, 5);
cout << (a->val) << endl;
}
我希望它会打印5,但它没有。我需要给一个给定的指针赋值,在函数内部。我该怎么做呢?
这是一个bug:
test* x = (test*)malloc(sizeof(test*));
应:
test* x = (test*)malloc(sizeof(test));
现在,让我们返回新分配的指针:
test* insert(int value) {
test* x = (test*)malloc(sizeof(test));
x->val = value;
return x;
}
int main() {
test* a = insert(5);
cout << (a->val) << endl;
// and let's free "a" while we can
free(a);
}
指针与其他东西没有什么不同:当用作函数参数时,它们是按值传递的。
因此,main()
中的insert(a,5)
将a
的副本传递给函数,并且函数中参数的更改对调用者来说是不可见的。
因此,当控制返回到main()
时,值a
不改变。它仍然是空指针,计算a->val
会给出未定义的行为。
通过引用修复任意一个传递。
void insert(test *&t, int value) // note the & here
{
test* x = (test*)malloc(sizeof(*x));
x->val = value;
t = x;
}
int main()
{
test* a = NULL;
insert(a, 5);
cout << (a->val) << endl;
}
还请注意,由于您弄错了,我已经纠正了传递给malloc()
的参数。你通过了sizeof(test *)
,真的需要通过sizeof(test)
。我使用了传递sizeof(*x)
的技术,因为即使(比如说)您将指针的类型更改为其他类型,它也会工作。
或传递指针给指针(test **
)
void insert(test **t, int value) // note the additional * here
{
test* x = (test*)malloc(sizeof(*x));
x->val = value;
*t = x; // note the additional * here
}
int main()
{
test* a = NULL;
insert(&a, 5); // also note the & here
cout << (a->val) << endl;
}
在以上两个选项中,通过引用(而不是指针)传递通常被认为是c++中更可取的。将指针传递给指针在C中很常见,但在c++中(大部分)是不鼓励的。
一般来说,在c++中最好使用new
操作符,而完全避免使用malloc()
。除其他外,它消除了获得错误的sizeof
操作数的可能性(如您所演示的)。所以,我们不用
test* x = (test*)malloc(sizeof(*x));
test* x = new test;