我怎么知道c中指针变量的分配内存大小

在这种情况下,我遇到了一些问题,请问你的想法。

main() { char *p=NULL; p=(char *)malloc(2000 * sizeof(char)); printf("size of p = %d\n",sizeof (p)); } 

在这个程序中它打印4个(char *)值,但我需要分配多少字节。

只知道指针分配了多少内存是不可能的。 执行sizeof (p)将得到编译时所需的指针变量p的大小,以及指针的大小。 也就是说,指针变量用于存储指针变量p的内存。 在p内部存储存储块的起始地址。

一旦你用malloc分配一些内存,它将返回内存块的起始地址,但是无法从中找到块的结尾,因为没有块的终止符。 您定义块的结尾,因此您需要通过任何方式识别它,因此将其存储在某处。 因此,您需要在某处保留块长度,以便知道p指向的块的结束位置。

注意:虽然内存分配结构跟踪已分配和未分配的块,但是我们可以从这些结构中知道分配的内存块长度,但这些结构不可供用户使用,除非任何库函数提供它们。 因此,使用此类function的代码不可移植(由@Rudy Velthuis指出)。 因此,最好自己跟踪结构。

您还可以为malloc实现一个包装器,并在malloc返回指针之前自由添加标签(如分配的大小和其他元信息)。 这实际上是c ++编译器通过引用虚拟类来标记对象的方法。 这是一个有效的例子:

 #include  #include  void * my_malloc(size_t s) { size_t * ret = malloc(sizeof(size_t) + s); *ret = s; return &ret[1]; } void my_free(void * ptr) { free( (size_t*)ptr - 1); } size_t allocated_size(void * ptr) { return ((size_t*)ptr)[-1]; } int main(int argc, const char ** argv) { int * array = my_malloc(sizeof(int) * 3); printf("%u\n", allocated_size(array)); my_free(array); return 0; } 

此方法优于具有大小和指针的结构

  struct pointer { size_t size; void *p; }; 

是你只需要替换malloc免费通话。 所有其他指针操作都不需要重构。

如果您想了解它,您需要在变量中跟踪它:

 char *p = NULL; int sizeofp = 2000*sizeof(char); p = (char *)malloc(sizeofp); printf("size of p = %d\n",sizeofp); 

在这种情况下你不能使用sizeof,因为p是一个指针,而不是一个数组,但是既然你已经分配了它,你就会知道:

 main() { size_t arr_size = 2000; char *p=NULL; p=malloc(arr_size * sizeof(char)); printf("size of p = %d\n",arr_size); } 

编辑 – 如果malloc无法分配您想要的大小,它将不会为您提供指向较小缓冲区的指针,但它将返回NULL。

虽然某些库可能允许您确定分配的缓冲区的大小,但它不是标准的C函数,您应该查看库的自己的文档。

但是,如果有许多地方需要知道已分配内存的大小,那么最简单的方法是将大小保持在指针旁边。 那是:

 struct pointer { size_t size; void *p; }; 

然后,每次使用malloc指针时,都会在size字段中记下大小。 但是,此方法的问题是每次使用时都必须转换指针。 如果您使用的是C ++,我建议使用模板类。 但是,在这种情况下,它也不难,只需创建与您拥有的类型一样多的结构。 所以举个例子

 struct charPtr { size_t size; char *p; }; struct intPtr { size_t size; int *p; }; struct objectPtr { size_t size; struct object *p; }; 

给定相似的名称,一旦定义了指针,就不需要额外的努力(例如转换)来访问数组。 使用的一个例子是:

 struct intPtr array; array.p = malloc(1000 * sizeof *array.p); array.size = array.p?1000:0; ... for (i = 0; i < array.size; ++i) printf("%s%d", i?" ":"", array.p[i]); printf("\n"); 

对于Windows,没有可移植的方式:

 #include  #include  #if defined( _MSC_VER ) || defined( __int64 ) /* for VisualC++ or MinGW/gcc */ #define howmanybytes(ptr) ((unsigned long)_msize(ptr)) #else #error no known way #endif int main() { char *x=malloc(1234); printf( "%lu", howmanybytes(x) ); return 0; }