我正确使用malloc吗?

时间:2010-12-03 08:38:41

标签: c malloc

美好的一天!

我需要在创建学生列表系统时使用malloc ....为了提高效率,我们的教授要求我们在结构上使用它,所以我创建了一个结构如下:

struct student {
       char studentID[6];
       char name[31];
       char course [6];
};
struct student *array[30];

每次我添加一条记录,就是当我使用malloc ...

array[recordCtr]=(struct student*)malloc(sizeof(struct student));
recordCtr++;
然后我就这样释放它。

 for(i = 0; i < recordCtr; i++){
       free(array[i]);
  } 

我是否正确使用malloc ???如果我像这样取而代之的是上面的循环,那会有什么影响。

free(array);

提前致谢。您的意见将受到高度赞赏。

10 个答案:

答案 0 :(得分:4)

你做得很好。

free(array);将是未定义的行为,因为array本身未通过malloc分配,因此您无法free它并且不需要 - 内存将是由编译器管理。

答案 1 :(得分:3)

一个好的建议是:

type *something;
something = malloc(n * sizeof(*something));

这是因为,如果您更改某些内容的类型,则无需更改各种其他代码。而sizeof实际上是一个编译器操作,它不会在运行时变成任何不同的东西。

另外,不要强制转换malloc返回的void *指针,没有理由在C中这样做,只是进一步将代码绑定在一起。

所以在你的情况下,不要这样做:

(struct student*)malloc(sizeof(struct student));

malloc(sizeof(**array));

答案 2 :(得分:2)

使用malloc的方式没有任何违法行为,但这不是一个列表,而是一个指针数组。

要使用列表,请不要提前修改大小并指向下一个元素。你可以使这种侵入性非侵入性。

对于侵入性列表,您将struct student * next放在学生的声明中。 对于非侵入式列表,您创建另一个struct student_list_node,其中包含struct student的实例和指针struct student_list_node * next;

这是非侵入式版本的一个例子:

struct student_list_node
{
  struct student data;
  struct student_list_node * next;
};

struct student_list_node * head;
struct student_list_node * tail;

struct student_list_node * addStudentToTail()
{
   struct student_list_node * newnode = (struct student_list_node *)(malloc( sizeof(struct student_list_node ) );
   /* check malloc did not fail or use a checking vesrion of malloc */
   if( !tail )
   {
      head = tail = newnode;
   }
   else
   {
      tail->next = newnode;
      tail = newnode;
   }
   return newnode; // which is also "tail"
}

int main()
{
   struct student_list_node * node = addStudentToTail();
   struct student * pstud = &node->data;
   /* write to pstud student details */
}

如果你确实想要使用数组,你可能想让它成为学生而不是学生*的数组,在这种情况下你可以使用calloc而不是malloc

struct student * array = (struct student *)calloc( 30, sizeof( student ) );

然后使用free(array)将是处理它的正确方法。如果稍后需要使用realloc,您还可以选择分配更多。 (小心这个:你必须保留原始指针的副本,直到你知道realloc成功为止)。

答案 3 :(得分:1)

数组本身未在堆上分配。假设它是一个全局变量,它在程序启动时分配在全局内存中,不需要被释放。免费拨打电话可能会破坏您的计划。

您当前的解决方案是正确的。

答案 4 :(得分:1)

你所做的是正确的。

您可以将*array[30]视为30个指针的数组 当你为每个指针分配内存时,你还需要在每个指针上调用free()。​​

答案 5 :(得分:1)

是的,您正确使用它。有更好的方法来组织存储比这个,但这将工作。至少在你需要超过30名学生之前......

请注意,您必须使用free()返回的每个指针调用malloc()。这意味着你对指针数组的循环是所选架构的正确方法。

您尝试在阵列上自由呼叫将无效。它调用未定义的行为,因为您将指针(到数组本身的基础)传递给free()而不是来自malloc()的调用。

答案 6 :(得分:1)

看起来很好。

你可以(如果它适合你的问题)一次性为所有30个结构分配空间

 struct student *array = (struct student *)malloc(30*sizeof(struct student));

当你想要处理空间时,你可以做

free(array)

答案 7 :(得分:1)

你所拥有的将会很好。正如其他人所提到的,你已经在堆栈上创建了一个指针数组,并且需要malloc并在你做的时候单独释放它们。

但是,您不必一次使用malloc并释放一个结构,您可以这样做:

int arraySize = 30;
student * ourArray = (student*)malloc(sizeof(student) * arraySize);

并且指针上的一个空闲将处理它。使用此指针,您仍然可以使用括号表示法,编译器将理解它是一个类型指针并且行为恰当,给您基本相同的东西。您使用哪种方法取决于您是否需要数组的动态大小或个人偏好。

希望有所帮助。

答案 8 :(得分:1)

使用NULL值初始化指向struct student的指针数组

for(i = 0; i < recordCtr; i++){
       array[i] = NULL;
  } 

如果array [i]不为NULL,则为空闲内存

for(i = 0; i < recordCtr; i++){
       if(NULL != array[i])
       {
           free(array[i]);
       }
  } 

答案 9 :(得分:1)

有一个简单的规则:每个malloc()都应与free()配对,并由malloc返回指针。不少,不多。