2010-12-03 82 views
3

美好的一天!我正确使用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); 

在此先感谢。您的意见将不胜感激。

回答

4

你很好。

free(array);将是不确定的,因为array本身没有通过malloc分配行为,因此你不能free它并不需要 - 内存会由编译器进行管理。

1

数组本身没有分配在堆上。假设它是一个全局变量,它在程序启动时被分配在全局内存中,不需要被释放。免费调用它可能会破坏你的程序。

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

+0

是的。它是一个全局变量 – newbie 2010-12-03 08:44:00

1

你在做什么是正确的。

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

1

是的,您正确使用它。有比这更好的方式来组织存储,但这会起作用。至少直到你需要超过30名学生...

请注意,您必须拨打free(),每个指针由malloc()返回。这意味着您对指针数组的循环是您选择的架构的正确方法。

您试图在数组本身上自由调用不起作用。它会调用未定义的行为,因为您正在传递一个指向free()的指针(指向数组本身的底部),该指针并非来自malloc()的调用。

1

看起来不错。

你可以(如果它符合您的问题)的所有30层结构中的一个分配空间去

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

whhen要处理的空间,那么你可以做

free(array) 
1

什么你将会工作得很好。正如其他人所提到的,你已经在堆栈上创建了一个指针数组,并且需要malloc并且像你一样分别释放它们中的每一个。

但是,你没有在同一时间使用malloc和free一个结构,你可以做这样的事情:

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

和一个免费的指针会照顾它。使用这个指针,你仍然可以使用括号表示法,编译器会明白它是一个类型化指针并且行为恰当,给你基本上相同的东西。您使用哪种方法取决于您是否需要阵列动态大小以及个人偏好。

希望有助于一些。

1

初始化您的指针数组结构学生空值

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

免费内存,如果数组[i]是不是空

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

我可以知道为什么我需要初始化数组并将其设置为NULL?谢谢。 – newbie 2010-12-03 09:00:13

+0

如果我不...... – newbie 2010-12-03 09:00:31

+0

@newbie:除非你初始化指针数组,否则它们可能包含垃圾值。如果您尝试释放垃圾价值,您的C运行时间往往会在一堆吸烟渣中崩溃。 – JeremyP 2010-12-03 09:28:34

3

一个好的技巧是要始终做到:

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

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

此外,不要投射malloc返回的void *指针,在C中没有理由这样做,它只是进一步将您的代码绑定在一起。

你的情况

所以,不要做:

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

malloc(sizeof(**array)); 
2

没有什么非法的你正在使用malloc的方式,但这不是一个列表,它是一个指针数组。

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

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

这是的非侵入式版本的exacmple:

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成功为止)。

1

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