我正确使用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); 

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

你做得很好。

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

一个好的建议就是:

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

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

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

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

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

 malloc(sizeof(**array)); 

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

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

对于一个侵入性列表,你将struct student * next放在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成功为止)。

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

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

你正在做的是正确的。

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

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

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

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

看起来很好。

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

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

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

 free(array) 

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

但是,您不必一次使用malloc并释放一个结构,您可以执行以下操作:

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

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

希望有所帮助。

使用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]); } } 

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