【问题标题】:How to find the size of dynamic array [duplicate]如何找到动态数组的大小[重复]
【发布时间】:2018-08-04 03:46:20
【问题描述】:

有什么方法可以找到在这段代码中为RandomArray 分配了多少字节

#include<stdio.h>
#include<stdlib.h>

    int main()
    {
    int *RandomArray;
    int n;
    srand(time(NULL));

    RandomArray=malloc(sizeof *RandomArray * (rand()%11));
    printf("%d  %d",sizeof(RandomArray),sizeof(*RandomArray));

    return 0;
    }

我也不知道上面的代码是否会有任何实际用途。但我是从编程的角度来看的。

【问题讨论】:

  • 不..需要自己跟踪。
  • 而且您不保存rand()%11 的结果并验证它是否大于零,因为...?
  • @DavidC.Rankin 好吧,malloc(0) 并不违法。
  • 也不是很有用……
  • 是的,明白了,这里的整个问题是,如果您不保存分配的大小,就没有魔杖可以挥动将其取回......这是其中之一自己在额头”类型的问题。

标签: c dynamic-memory-allocation


【解决方案1】:

啊,这是实验代码。有趣的东西在那里。

  • 您将为N 整数分配内存,其中N 介于010 之间,包括010
  • 然后您将sizeof 应用于指针 (int*) 及其指向的内容 (int)。分配多少内存并不重要。此行的输出将是相同的。

  • 这里没有错误检查。如果是,您无法确定它是否完全成功,因为rand() 可能会给出0 作为结果。您需要将其存储在某处并检查它是否为0,因为在这种情况下malloc 可能会或可能不会返回NULL

  • 打印sizeof 返回的内容应该使用%zu 格式说明符来完成。它返回size_t

  • 为了更清楚,记住它是一个指向动态分配内存的指针。 RandomArray 不是一个数组——它是一个指向连续内存的指针。这不会使它成为数组。它仍然是一个指针。而您想应用的sizeof 技巧认为RandomArray 是一个数组将不起作用。一般来说,我们会跟踪它 - 使用一些变量。但是在这里你不知道你分配了多少内存。
  • malloc 可能会在您将0 传递给它时返回NULL。单独处理那个案子。如果你得到sz!=0 并在RandomArray 中得到NULL 抛出错误。

      size_t sz = rand()%11;
      RandomArray = malloc(sz);
      if(!RandomArray && sz){
         perror("malloc");
         exit(EXIT_FAILURE);
      }
    

在所有这些讨论之后 - 简短的回答是,使用此设置 到目前为止没有使用代码(您编写的代码)。你不知道 rand() 在 malloc 内的那个案例上返回了什么。

【讨论】:

    【解决方案2】:

    是的,通过将大小保存在变量中:

    int main()
    {
        int *RandomArray;
        int n;
        srand(time(NULL));
    
        size_t size = rand() % 11;
        if(size == 0)
        {
            fprintf(stderr, "Size 0, no point in allocating memory\n");
            return 1;
        }
    
        RandomArray = malloc(size * sizeof *RandomArray)
        if(RandomArray == NULL)
        {
            fprintf(stderr, "no memory left\n");
            return 1;
        }
        printf("%zu  %zu\n", sizeof(RandomArray), size);
    
        // don't forget to free the memory
        free(RandomArray);
    
        return 0;
    }
    

    请注意,sizeof(RandomArray) 返回指向 int 的指针的大小 需要存储在内存中,sizeof(*RandomArray) 返回你的大小 一个int

    别忘了释放内存。

    【讨论】:

      【解决方案3】:

      由于表达式*RandomArray 的类型为int,因此sizeof(*RandomArray) 的计算结果为sizeof(int)。它不会告诉您分配了多少内存。

      当动态分配内存时,您需要自己跟踪分配了多少。在上述情况下,您需要将随机数存储在某个地方,以便知道该数量是多少。

      【讨论】:

        【解决方案4】:

        sizeof(RandomArray) 总是产生 4 个字节(等于指针大小),如果你想知道为RandomArray 分配了多少字节

        /* Since its implimentation dependent, so I'm not 
          advising you to access RandomArray[-1], also proper type casting needed */
        printf("memory allocated = %d \n",RandomArray[-1]);
        

        来自

        Denis Ritchie & Kernighan 的 C 编程语言

         typedef long Align;    /* for alignment to long boundary */
           union header {         /* block header */
               struct {
                   union header *ptr; /* next block if on free list */
                   unsigned size;     /* size of this block */
               } s;
               Align x;           /* force alignment of blocks */
           };
           typedef union header Header;
        

        从不使用Align 字段;它只是强制每个标题在最坏情况的边界上对齐。 在malloc 中,请求的字符大小被四舍五入到适当的header-sized 单位数;将被分配的块包含 多一个单位,为header 本身,这是记录在 size 标头字段。 ma​​lloc 返回的指针指向空闲空间,而不是标题本身

                      RandomArray[-1]                      
           -----------------------------------------
           |        |     SIZE     |               |
           -----------------------------------------
                                                  RandomArray
        
                -> a block returned by malloc 
        

        【讨论】:

        • 标准中是否有任何内容可以保证malloc 在指针返回之前保存大小?我不认为你可以转发。
        • 但这不只是一个实现细节吗?所有malloc 实现都这样做吗?
        • 如果申请的内存无法分配,则返回空指针。如果请求的空间大小为零,则行为由实现定义:要么返回空指针。
        • 虽然这个答案确实提供了有关常见实现细节的有用信息,但不幸的是它是一个实现细节,即绝对不能保证以这种方式工作。此外,索引RandomArray[-1] 几乎肯定会失败——你需要一个比这更复杂的演员才能正确地做到这一点。
        • 这只是存储分配器的一个示例(来自 K&R 示例 8.7);该标准不强制要求这样的标题。无论如何,我不确定你会从这些知识中获得什么。尝试访问RandomArray[-1] 是未定义的行为,甚至形成指针RandomArray - 1 的行为也是未定义的。
        【解决方案5】:

        sizeof 操作符在编译时工作,除了操作数是变长数组,动态内存分配是运行时操作的情况。 在表达式中:

        printf("%d  %d",sizeof(RandomArray),sizeof(*RandomArray));
        

        RandomArray 的类型是int **RandomArray 的类型是int

        因此,表达式等价于:

        printf("%d  %d",sizeof(int *),sizeof(int));
        

        sizeof 将产生一个整数常量的结果,因此,无论分配给RandomArray 的内存大小如何,每次都会得到相同的结果。

        How to find the size of dynamic array

        从您动态分配内存的点开始跟踪 大小


        请注意,您在分配内存时将rand()%11 返回的值乘以sizeof *RandomArrayrand() 也可能返回0,这将导致malloc(0)。很高兴知道(来自C Standards#7.22.3):

        ....如果请求的空间大小为零,则行为是实现定义的:要么返回空指针,要么行为就好像大小是某个非零值,除了返回的指针应不能用于访问对象。

        【讨论】:

          猜你喜欢
          • 2014-09-13
          • 2015-05-06
          • 2012-11-15
          • 1970-01-01
          • 1970-01-01
          • 2015-08-02
          • 2011-05-05
          • 2014-10-06
          • 2021-01-15
          相关资源
          最近更新 更多