我正确使用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()
配对。 不少,不是更多。