如何动态计算动态分配的内存的大小

时间:2015-08-19 13:06:53

标签: c malloc

考虑如下代码:

int i, a_size, s_size, n;
char **a;

a_size = 100; // examples
s_size = 10;

a = malloc(a_size * sizeof(char*));
for (int i = 0; i < a_size; i++)
    a[i] = malloc((s_size) * sizeof(char)); 

现在,我想动态计算数组中有多少元素(因此,忽略a_size)。这是正确的方法吗?

4 个答案:

答案 0 :(得分:4)

一般情况下你不能这样做,你应该自己处理这种簿记,但有一种可能性就是将额外的行指针设置为NULL(又名定点):

a = malloc((a_size + 1) * sizeof(char*));   // allocate additional row pointer
for (int i = 0; i < a_size; i++)            // allocate rows
    a[i] = malloc(s_size); 
a[a_size] = NULL;                           // set sentinel row to NULL

然后,您可以通过遍历行指针来确定大小,直到找到NULL行。请注意,如果您经常这样做,或者行数可能很大,这可能效率很低。

答案 1 :(得分:3)

TL; DR 指针不存储有关分配的内存大小的任何信息。因此,没有直接的API类型可以确定分配的大小。

但是,一些动态内存分配库提供了一些选项来实际获取有关分配大小的信息,但这是非标准且严重依赖于实现。

也就是说,您可以想到一种方法,您可以明确标记存储到数据中的数据结尾(检查sentinel value概念)动态分配的内存(因此,基本上,标记分配的内存的结束),但同时,这是你必须要处理的事情。

请记住。正如Mr. Paul R正确提到的那样,这种哨兵价值方法可能效率很低,这种方法可能有很多限制,例如

  • 您不能将哨兵值作为合法值之一。
  • 如果在某种情况下,Sentinel值不会出现在分配的最后,它可能会提供有关分配大小的错误信息。
  • 你总是会分配一些未被有效使用的内存(用于放置哨兵)

等等。

恕我直言,最好的方法是,在一个单独的变量中保持分配大小的轨道,并在必要时用指针传递它。

答案 2 :(得分:0)

首先动态分配101个一维数组。

分配的字符总数等于产品s_size * s_size

你可以使用哨兵,但一般来说很难为哨兵选择一个值。

所以你应该自己将这些值存储在变量中。

您需要确定存储在一个一维数组中的字符串的长度,其中元素类型为char,您应该使用标头strlen中声明的标准C函数<string.h>例如< / p>

strlen( a[0] )

答案 3 :(得分:0)

实现所需簿记机制的一种可能性(尽管这可能不是一个好方法)是实现自定义分配,大小和自由函数,可以通过以下方式绘制草图,其中size_t是类型用于数组的大小;该方法类似于Pascal样式字符串。

对于分配,更多地分配sizeof(t_size)内存,将其写入已分配块的beginnig,并返回指向第一个sizeof(t_size)字节之后的指针。

要获得大小,只需在数组前查看sizeof(t_size)个字节。

对于自由函数,从存储大小的位置开始释放存储块,这是实际分配的块的开头。