跟踪malloc分配的内存量

在对SO的相关问题进行快速扫描之后,我推断出没有能够检查malloc已分配给指针的内存量的函数。 我正在尝试使用C中的简单char *来复制一些std :: string基本function(主要是动态大小),并且不想一直调用realloc。 我想我需要跟踪已经分配了多少内存。 为了做到这一点,我正在考虑创建一个包含字符串本身的typedef和一个当前分配的内存量的整数,如下所示:

typedef struct { char * str; int mem; } my_string_t; 

这是一个最佳解决方案,或者您可以建议一些能够带来更好结果的方案吗? 在此先感谢您的帮助。

您需要在同一内存块中为长度和字符串分配空间。 这可能是您对结构的意图,但是您只为指向字符串的指针保留了空间。

必须分配空间以包含字符串的字符。

例如:

 typedef结构
 {
     int num_chars;
     char string [];
 } my_string_t;

 my_string_t * alloc_my_string(char * src)
 {
     my_string_t * p = NULL;
     int N_chars = strlen(src)+ 1;

     p = malloc(N_chars + sizeof(my_string_t));
    如果(p)
     {
          p-> num_chars = N_chars;
          strcpy(p-> string,src);
     }
    返回p;
 }

在我的示例中,要访问指向字符串的指针,请解决my_string_tstring成员:

 my_string_t * p = alloc_my_string(“hello free store。”);
 printf(“%d字节的字符串是'%s'\ n”,p-> num_chars,p-> string);

请注意,由于分配了用于存储字符的空间,因此您正在获取字符串的指针。 您分配的资源是字符的存储,获得的指针是对分配的存储的引用。

在我的示例中,分配的内存按顺序排列如下:

 + ---- ---- + ---- + ---- + ---- + ---- + ---- + ---- + ---- + ---- + + ---- ---- + ---- + ---- + ---- + ---- + ---- + ---- + ---- + ---- + + ---- + ---- +
 |  00 |  00 |  00 |  11 |  'H' |  'E' |  'L' |  'L' |  'O' |  20 |  'F' |  'R' |  'E' |  'E' |  20 |  'S' |  'T' |  'O' |  'R' |  'E' |  '' |  00 |
 + ---- ---- + ---- + ---- + ---- + ---- + ---- + ---- + ---- + ---- + + ---- ---- + ---- + ---- + ---- + ---- + ---- + ---- + ---- + ---- + + ---- + ---- +
 ^^ ^
 ||  |
 p |  |
  p-> num_chars p-> string

请注意, p->string值不存储在已分配的内存中,它是从分配的内存开头起的四个字节,紧跟在(假定的32位,四字节)整数之后。

您的编译器可能要求您将灵活的C数组声明为:

 typedef结构
 {
     int num_chars;
     char string [0];
 } my_string_t;

但缺少零的版本据称符合C99标准。

您可以完成没有数组成员的等效事项,如下所示:

 typedef结构
 {
     int num_chars;
 } mystr2;

 char * str_of_mystr2(mystr2 * ms)
 {
     return(char *)(ms + 1);
 }

 mystr2 * alloc_mystr2(char * src)
 {
     mystr2 * p = NULL;
     size_t N_chars = strlen(src)+ 1;

     if(N_chars num_chars =(int)N_chars;
          strcpy(str_of_mystr2(p),src);
     }
    返回p;
 } 

 printf(“%d字节的字符串是'%s'\ n”,p-> num_chars,str_of_mystr2(p));

在第二个示例中,等效于p->string的值由str_of_mystr2()计算。 它将与第一个示例具有大致相同的值,具体取决于编译器设置打包结构的结尾。

虽然有些人会建议跟踪一个size_t的长度,但我会查看一些老Dobb博士关于我不同意的文章。 支持值大于INT_MAX对于程序的正确性具有可疑价值。 通过使用int,可以编写assert(p->num_chars >= 0); 并测试一下。 使用unsigned时,您可以编写类似assert(p->num_chars < UINT_MAX / 2);的等效测试assert(p->num_chars < UINT_MAX / 2); 只要您编写包含运行时数据检查的代码,使用签名类型就很有用。

另一方面,如果你正在编写一个处理超过UINT_MAX / 2个字符的字符串的库,我向你致敬。

这是显而易见的解决方案。 当你在它时,你可能想要一个结构成员来维护实际使用的已分配内存量。 这将避免必须一直调用strlen(),并使您能够支持非空终止字符串,就像C ++ std :: string类那样。

这就是它在更新世中的表现,这就是你今天应该怎么做的。 你不知道malloc没有提供任何可移植的,支持的机制来查询分配块的大小。

更常见的方法是包装malloc(和realloc)并保留大小和指针列表
这样您就不需要更改任何字符串函数。

编写包装函数。 如果您使用的是malloc,那么无论如何都应该这样做。

有关“编写实体代码”的示例

我想你可以使用malloc_usable_size 。