从C函数返回指针是好/坏设计?

时间:2015-06-03 14:17:26

标签: c arrays pointers static return

我想知道来自C函数的返回指针是好/坏设计?如果这是一个不好的做法,在下面的例子中,这将是一个好习惯:

问题是继续的一部分: c function return static variable

<{1>}文件中的

data.h
#include <stdio.h> #include <stdlib.h> typedef struct { int age; int number; } person; person * getPersonInfo();

中的

data.c
#include "data.h" static struct person* person_p = NULL; person * getPersonInfo() { person_p = (struct person*)malloc(10 * sizeof(struct person)); return person_p; }

中的

main.c

基本上,#include "data.h" int main() { person* pointer = getPersonInfo(); return 0; } 文件中的main函数需要获取静态指针main所指向的数组的所有元素的值,如果这不是一个好习惯,那么一个好的做法应该是什么?

4 个答案:

答案 0 :(得分:4)

它不好的唯一原因是因为你后面没有任何内存管理结构。在您当前的代码中,您有内存泄漏,因为您通过malloc()分配person结构但不释放它。

考虑编写一个包装器函数来为你处理内存管理:

void freePerson(struct person * personToDelete)
{
    free(personToDelete);
}

然后在你的主要:

int main()
{
   person* pointer = getPersonInfo();
   freePerson(pointer); // After you are done using it
   return 0;
}

我还要警告不要施放malloc()的结果。根据我的经验,它可能导致未定义的行为。

答案 1 :(得分:2)

将指针返回私有变量是不好的做法。此外,使用当前设计,您的.c文件只能有一个person对象的实例。

并且几乎不用说,动态分配对象的相同代码也应该负责释放它。根据设计编写的代码,以便程序中的某些其他模块可以清理混乱,最终会导致内存泄漏。

如果您正在编写至少有些复杂的数据类型,您需要限制对私有变量的访问,拥有结构的多个实例等,那么最好使用“opaque type”。示例(未测试):

// data.h

#ifndef DATA_H 
#define DATA_H

#include <stdio.h>
#include <stdlib.h> 

typedef struct person person; // opaque type

person* person_create (void);

void person_delete (person* p);

void person_set_age (person* p, int age);
int  person_get_age (const person* p);
// ... and so on, setters/getters

#endif // DATA_H

// data.c

#include "data.h"

struct
{
  int age;
  int number;
} person;    


person* person_create (void)
{
  return malloc(sizeof(struct person));
}

void person_delete (person* p)
{
  free(p);
}

void person_set_age (person* p, int age)
{
  p->age = age;
}

int person_get_age (const person* p)
{
  return p->age;
}

//来电者:

#include "data.h"

int main()
{
   person* p = person_create();

   person_set_age(p, 50);
   printf("%d", person_get_age(p));

   person_delete(p);
   return 0;
}

需要考虑的一些事项:

  • 始终在h文件中使用标题保护。
  • 永远不要对C函数使用空参数列表()(但总是在C ++中使用)。
  • 不要在C中强制转换malloc的结果(但总是在C ++中)。
  • 如果malloc失败,则需要在此代码中添加一些错误处理。

答案 2 :(得分:0)

决定的问题比其他事情更重要。

只要您了解每位专业人士及其他人,这两个选项都有效

返回指针专业人士:

  1. 内存分配的封装
  2. 动态支持动态内存大小
  3. 返回指针缺点:

    1. 只有一个可能的参数
    2. 每次都要在堆上分配内存
    3. 接受指针作为输入专业正好相反:

      1. 多个输出参数
      2. 内存不必在堆上分配,调用者可以使用其堆栈上的变量作为输出参数
      3. 接受指针作为输入缺点:

        1. 没有封装内存分配
        2. 动态内存大小不支持 - 大小必须固定或预先指定
        3. 在您的具体示例中,我使用输出参数,因为它是固定大小的,并且可以在不动态分配内存的情况下轻松调用。

答案 3 :(得分:0)

要成为一个好的设计,你必须有一个匹配的函数,在不再需要时释放已分配的内存。