Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在c中从函数返回指针是一种好的做法吗?_C_Function_Pointers - Fatal编程技术网

在c中从函数返回指针是一种好的做法吗?

在c中从函数返回指针是一种好的做法吗?,c,function,pointers,C,Function,Pointers,例如: 我想知道这在c语言中是否是一个好的实践?我认为问题在于免费(a);我认为您应该添加一个release\u point()函数。查看上的C示例。这是一种结构化代码的方法,您可以在界面的一侧完全管理内存。返回指针非常常见。问题或需要的纪律是确定释放内存的责任在哪里。这个例子之所以有味道,是因为不清楚它是否需要在main()中被释放。如果您有一个一致的系统知道哪些函数返回必须被释放的指针(例如在函数名中使用单词create或new),那么管理内存就更容易了 int *point() { in

例如:


我想知道这在c语言中是否是一个好的实践?

我认为问题在于免费(a);我认为您应该添加一个release\u point()函数。

查看上的C示例。这是一种结构化代码的方法,您可以在界面的一侧完全管理内存。

返回指针非常常见。问题或需要的纪律是确定释放内存的责任在哪里。这个例子之所以有味道,是因为不清楚它是否需要在main()中被释放。

如果您有一个一致的系统知道哪些函数返回必须被释放的指针(例如在函数名中使用单词
create
new
),那么管理内存就更容易了

int *point() {
 int *q = malloc(sizeof(int));
 *q=20;
 return q;
}

int main() {
    int *a = point();
    free(a);
}

<> P>唯一一个真正的危险,就是返回一个指向内存分配的指针:如果你的库是在Windows上编译的,并链接到Visual C++运行库(MVCRT)的一个实例,例如,它是静态链接到它的,并且一个客户端程序被链接到另一个实例,例如,它被链接到DLL,然后它们都有不同的malloc竞技场,程序无法释放库返回的指针。任何这样做的尝试都可能导致程序崩溃。

我主张始终使用您自己的函数来释放库返回的内存,除非您返回的是诸如字符串之类的琐碎内容

这样做的原因是,如果您更改返回内容的结构,使简单的
空闲
不再足够(因为您向返回的对象指针中添加了需要释放的已分配内存),则客户端将不需要更改其代码;您只需更改现有的免费函数即可


因此,拥有自己的免费函数可以将客户端与库返回的对象结构隔离开来,让您可以在不影响客户端的情况下自由更改对象的结构。

这通常是一种很好的做法,但您的示例是极坏做法的少数情况之一。对于较小且不包含(并且永远不需要包含)指针的单个对象,不应使用动态分配和指针。使用
malloc
获取一个4字节的
int
,在计入簿记开销后,至少会使用16个字节,但可能更重要的是,这意味着您必须担心可能的分配失败(以及如何处理),并管理何时释放对象

一些不应该这样分配的对象示例:

  • 任何基本类型
  • 有序对/坐标/向量/矩阵等(只要它们是固定尺寸)
  • ip地址
  • 颜色值

当然,在分配这些对象的数组时,分配并返回指向这些对象的指针是有意义的。

不同意。如果需要的清理量大于
free()
,则是,添加析构函数。但是如果你的清理功能只不过是
voidrelease(mytype*p){free(p);}
,那么你的清理功能就没有必要了。您可以记录任何使用您的数据类型的人需要调用
free()
,就像您可以记录他们应该调用您的自定义释放/析构函数一样简单。另外,每个人都知道
free()
的作用。@Chris:拥有一个release\u point()函数可以确保,如果将来需要进行任何清理,则不需要重构整个应用程序。同意,但point应该被称为create\u point()。这样一来,我马上就觉得我应该在以后毁掉这一点。@Chris:我同意你的观点,free()是所有需要的东西。但是Windows及其多个内存堆(释放、调试和谁知道是什么)意味着DLL最好为其所有alloc函数定义清理函数。更正:从整个代码示例中可以清楚看出,但是如果API用户没有访问
point()
的代码,则不清楚。当函数返回指针时,记录它是否需要
free()
-d(或者如果需要使用其他更专门的清理)。是的,当函数就在您面前时,这很容易。如果把它埋在一个10000行的图书馆里,就不那么容易了。:)根据目前的答案,这显然是一个主观问题。似乎并没有客观的标准来判断这种编码实践的好坏,也有支持和反对它的论据。@Mark:这是胡说八道。当然,有人赞成或反对返回指针,但那是因为有时返回指针是明智的,有时则不然。一个好的答案,因为你似乎有疑问,应该在上面解释什么时候返回指针是一个好的实践,以及为什么返回指针是/不是。下次你决定投票决定关闭一个问题时,我建议你在点击它之前阅读关闭原因。接近的理由没有说“主观”。它说的是“主观的和有争议的”。真正重要的是“辩论”部分。毕竟,没有人想要一场火焰战。但这个问题,像许多其他主观问题一样,可以得到客观的回答@例如,DGM的回答是客观的。它观察了这种情况有多普遍,解释了返回指针应该如何执行,解释了OP示例的问题所在。我同意jalf。此问题不符合结案标准。事实上,一些答案包含了一些对C初学者有用的信息。
int *createPoint()
{
    int *q = malloc(sizeof(int));
    if (*q)
       *q = 20;
    return q;
}