返回在函数内声明的指针被认为是不好的做法?例如:
int* foo(void)
{
int * ret_val = 1234;
return ret_val;
}
我相信你应该使用:
static int * ret_val = 1234;
但话又说回来,将范围内的内存返回到你的范围内是不是仍然被认为是不好的做法?
答案 0 :(得分:2)
返回指针不是问题,只要它指向仍在范围内的内存,例如动态分配的内存,全局数据或仍然存在于调用堆栈中的局部变量。
上面代码的问题在于,您在取消引用指针时没有为其指定任何内容。这样:*ret_val = 1234;
将值1234
分配给ret_val
指向的地址,但ret_val
未分配任何内容。
如果另一方面你这样做了:
int* foo(void)
{
int * ret_val;
ret_val = malloc(sizeof(int));
*ret_val = 1234;
return ret_val;
}
这很好,因为你正在返回一个指向动态分配内存的指针。
答案 1 :(得分:2)
罪魁祸首是
*ret_val = 1234;
应用了未初始化的指针。
我相信你会想要使用:
static int* ret_val;
不,要修复你可以使用
int* foo() {
static int_val = 1234;
return &int_val;
}
但如果那是你真正想要的东西,这是有争议的。该函数的所有调用者将共享int_val
的相同实例。
答案 2 :(得分:0)
如果你返回一个指向局部变量的指针,这是一个非常糟糕的做法,因为你将有一个悬空指针。
<input id="file" type="file">
<div id="binary"></div>
但有时它可能有用:
int* foo(void)
{
int a = 1337;
return &a; //Don't do this!
}
无论如何,你应该避免返回指针,因此不存在内存泄漏的风险。
答案 3 :(得分:0)
除了使用ret_val
而不分配它之外,从函数返回指针是公平的做法,尽管需要特别小心:
size
参数或全局常量答案 4 :(得分:0)
你应该考虑:
int *foo() {
int *ret_val = new int(1234);
return ret_val;
}
代替(错误代码):
int* foo(void)
{
int * ret_val;
*ret_val = 1234;
return ret_val; // dangling pointer!
}
否则你会有悬空指针(第二个例子)。 显然不要忘记释放内存。 您还应该考虑使用智能指针: https://en.wikipedia.org/wiki/Smart_pointer
当你指定C ++和C语言时,上面的代码是C ++(operator new),请参考(例如)@Mattia F.回答ANSI C。
答案 5 :(得分:0)
指针就像一个快捷方式或超链接。仅创建快捷方式不会安装程序。创建超链接并不会神奇地设置整个网站。
与指针相同:int*
是指向整数的指针。它本身不是整数。因此,在尝试跟踪指针之前,必须确保指针指向有意义的内容。
这样做的一种方法是创建一个整数并设置指向它的指针:
int* ret_val = new int;
这将创建一个整数(new
运算符),然后将ret_val
指针设置为指向它。
通过new
创建的对象一直存在,直到您通过delete
或应用程序结束时明确销毁它们为止。因此,如果函数中有new int
,即使函数结束,也可以安全地访问它。
如果您将指针ret_val
设置为不是一个新的整数,而是设置为一个现有的局部变量,即
int myInteger;
int* ret_val = &myInteger;
在这种情况下,ret_val
指向局部变量myInteger
,当包含声明的范围结束时,该变量将被销毁。你最终得到一个悬垂的指针,引用不存在的东西(想想:破坏的超链接)。使用这样的指针可能会导致未定义的行为。它可能会使程序崩溃,但它也可以默默地接受它,修改内存中的一些随机空间。
所以,形状的函数:
int* foo(void)
{
int* ret_val = new int;
*ret_val = 1234;
return ret_val;
}
使用安全。它不一定是一个好习惯:这种函数的用户必须知道它创建了一个新的整数,稍后 - 在某个时刻 - 某人应该delete
。这样做的功能通常以某种方式强调这种行为,例如通过它的名字。例如,allocateInt()
清楚地表明它创建了以后应该删除的内容。相反,getInt()
表明整数已经存在,并且没有创建任何新内容。