在C中的堆上分配数组

Posted

技术标签:

【中文标题】在C中的堆上分配数组【英文标题】:Allocating array on heap in C 【发布时间】:2019-01-09 05:42:57 【问题描述】:

我在堆上分配一组“Todo”结构,如下所示:

struct Todo *todos = malloc(n * sizeof(*todos));

我的理解是,我现在已经为我所有的 n 个 Todo 结构分配了内存。因此,如果我想保存一些值,我可以这样做:

todos[i].id = 1;

现在的问题是,如果我尝试使用 free(&todos[i]); 释放该内存,我会收到一条错误消息,告诉我我尚未分配该指针。

我现在的问题是,我是否只需要释放 todos 数组而不是单独释放每个元素?

【问题讨论】:

***.com/questions/4641476/… 你只需要在你保存的指针上调用 free,即free(todos); Using Dynamic Memory allocation for arrays的可能重复 详细信息:“释放todos 数组” --> todos 是一个指针,而不是一个数组free(todos); 释放由todos 分配的内存指针。 【参考方案1】:

作为参考,你总是这样做:

WhateverTypeInTheWorld *var1 = malloc(whateveryouwanttocompletearray);

那么,你必须这样做

free(var1);  /* use the same value you received from malloc() */

要返回内存...因为您只执行了一个malloc(),您可以只执行一个free() 并将您从malloc() 获得的指针传递给它相同的指针

当你写作时:

free(&todos[i].i);

您传递的是i-esim 元素字段i 的地址,而不是您从malloc() 收到的指针。可能你明白你可以释放你收到的部分内存......但它不能那样工作......你以块的形式获取内存,并且你必须以从 malloc 收到的相同块返回它。

【讨论】:

【参考方案2】:

Some programmer dude的answer的一点背景

C11 标准,7.22.3.3“free 函数”,第 2 段:

free 函数使ptr 指向的空间被释放,也就是说,可用于进一步分配。如果ptr 是空指针,则不会发生任何操作。否则,如果参数与内存管理函数之前返回的指针不匹配,或者如果空间已通过调用 free 或 realloc 被释放,行为未定义.

[我强调]

背景(第二级...)通常,您不仅收到了从指针开始的内存,而且在需要的指针地址之前还有某种(机器/操作系统特定的)控制块再次释放内存。

您可能会尝试通过读取指针之前的一些字节来查看此控制块(只是出于好奇),但请注意这实际上也是未定义的行为(所以不要曾经在生产代码中执行此操作!)并可能导致您的程序崩溃。

【讨论】:

【参考方案3】:

您已经为您的Todo 结构所有分配了一个单独的内存块。您不能释放单个元素。就像您不应该释放非堆分配数组的元素一样。

malloc(或calloc)的每次调用都应与对free单个调用匹配。

【讨论】:

感谢您的快速回复。因此,如果我像这样调用免费:free(todos);它会为我所有的 todo 结构释放整个内存块,对吗? @user2403221 是的,这是准确的。

以上是关于在C中的堆上分配数组的主要内容,如果未能解决你的问题,请参考以下文章

JVM-堆

两个或多个线程如何在它们分配的堆上共享内存?

C# / .Net Framework 中的堆大小 - 它可以增长吗?如何增长? [复制]

java - 如何在java中的堆上单独获取所有对象消耗的运行时内存

Java中对象都是分配在堆上吗?你错了!

jvmiz9是什么意思