跟踪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_t
的string
成员:
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 。