这个问题在这里已有答案:
在这种情况下,我遇到了一些问题,你能不能取悦你的想法。
main()
{
char *p=NULL;
p=(char *)malloc(2000 * sizeof(char));
printf("size of p = %d\n",sizeof (p));
}
在这个程序中它打印4(char *)值,但我需要分配多少字节。
您还可以为malloc实现一个包装器,并在malloc返回指针之前自由添加标签(如分配的大小和其他元信息)。这实际上是c ++编译器通过引用虚拟类来标记对象的方法。这是一个有效的例子:
#include <stdlib.h>
#include <stdio.h>
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和免费电话。所有其他指针操作都不需要重构。
只知道指针分配了多少内存是不可能的。做sizeof (p)
将获得指针变量p
的大小,它在编译时需要,并且它是指针的大小。也就是说,指针变量用于存储指针变量p
的内存。在p
内部存储内存块的起始地址。
一旦你用malloc
分配一些内存,它将返回内存块的起始地址,但是无法从中找到块的结尾,因为没有块的终止符。您定义块的结尾,因此您需要通过任何方式识别它,因此将其存储在某处。因此,您需要在某处保留块长度,以便知道p
指向的块的结束位置。
注意:虽然内存分配结构跟踪已分配和未分配的块,但是我们可以从这些结构中知道分配的内存块长度,但这些结构不可供用户使用,除非任何库函数提供它们。因此,使用此类功能的代码不可移植(由@Rudy Velthuis指出)。因此,最好自己跟踪结构。
虽然某些库可能允许您确定已分配缓冲区的大小,但它不是标准的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 <stdio.h>
#include <malloc.h>
#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;
}
如果您想了解它,您需要在变量中跟踪它:
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。