美好的一天!
我需要在创建学生列表系统时使用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);
提前致谢。您的意见将受到高度赞赏。
答案 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返回指针。不少,不多。