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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7202069/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 09:29:43  来源:igfitidea点击:

how can i know the allocated memory size of pointer variable in c

cpointerssizememory-managementmalloc

提问by RoCkStUnNeRs

I have faced some problem in this case can you please your ideas.

在这种情况下,我遇到了一些问题,您能否请您提出意见。

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

In this program Its print the 4 that (char *) value,but i need how many bytes allocated for that.

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

回答by StefanW

You could also implement a wrapper for malloc and free to add tags (like allocated size and other meta information) before the pointer returned by malloc. This is in fact the method that a c++ compiler tags objects with references to virtual classes. Here is one working example:

您还可以为 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;
}

The advantage of this method over a structure with size and pointer

这种方法相对于具有大小和指针的结构的优势

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

is that you only need to replace the mallocand freecalls. All other pointer operations require no refactoring.

就是你只需要替换mallocfree调用。所有其他指针操作都不需要重构。

回答by phoxis

It is impossible to know how much memory was allocated by just the pointer. doing sizeof (p)will get the size of the pointer variable pwhich it takes at compile time, and which is the size of the pointer. That is, the memory the pointer variable takes to store the pointer variable p. Inside pthe starting address of the memory block is stored.

仅凭指针无法知道分配了多少内存。这样做sizeof (p)将获得p在编译时需要的指针变量的大小,这是指针的大小。也就是说,指针变量用来存储指针变量的内存p。里面p存放的是内存块的起始地址。

Once you allocate some memory with mallocit will return the starting address of the memory block, but the end of the block cannot be found from it, as there is no terminator for a block. You define the end of the block therefore you need to identify it by any means, so store it somewhere. Therefore you need to preserve the block length somewhere to know where the block which is pointed to by pends.

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

Note:Although the memory allocation structure keeps track of allocated and unallocated blocks, therefore we can know the allocated memory block length from these structures, but these structures are not available to be used by the users, unless any library function provides them. Therefore a code using such feature is not portable (pointed by @Rudy Velthuis) . Therefore it is the best to keep track of the structure yourself.

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

回答by Shahbaz

Although it may be possible that some libraries allows you to determine the size of an allocated buffer, it wouldn't be a standard C function and you should be looking at your library's own documentations for this.

尽管某些库可能允许您确定分配缓冲区的大小,但它不是标准的 C 函数,您应该查看库自己的文档以了解这一点。

However, if there are many places that you need to know the size of your allocated memory, the cleanest way you could do it is to keep the size next to the pointer. That is:

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

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

Then every time you mallocthe pointer, you write down the size in the sizefield also. The problem with this method however is that you have to cast the pointer every time you use it. If you were in C++, I would have suggested using template classes. However, in this case also it's not hard, just create as many structs as the types you have. So for example

然后每次你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;
};

Given similar names, once you define the pointer, you don't need extra effort (such as casting) to access the array. An example of usage is:

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

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");

回答by user411313

There is no portable way but for windows:

除了 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;
}

回答by Paul

You need to keep track of it in a variable if you want to know it for later:

如果您想稍后知道它,您需要在变量中跟踪它:

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

回答by MByD

You cannot use the sizeof in this case, since pis a pointer, not an array, but since you allocate it, you already know:

在这种情况下您不能使用 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);
}

Edit - If the malloc fails to allocate the size you wanted, it won't give you a pointer to a smaller buffer, but it will return NULL.

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