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

问题描述 投票:3回答:6

这个问题在这里已有答案:

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

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

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

c pointers size memory-management malloc
6个回答
5
投票

您还可以为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和免费电话。所有其他指针操作都不需要重构。


3
投票

只知道指针分配了多少内存是不可能的。做sizeof (p)将获得指针变量p的大小,它在编译时需要,并且它是指针的大小。也就是说,指针变量用于存储指针变量p的内存。在p内部存储内存块的起始地址。

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

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


3
投票

虽然某些库可能允许您确定已分配缓冲区的大小,但它不是标准的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");

2
投票

对于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;
}

1
投票

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

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

1
投票

在这种情况下你不能使用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。

© www.soinside.com 2019 - 2024. All rights reserved.