【问题标题】:C realloc not changing arrayC realloc 不改变数组
【发布时间】:2016-12-15 03:11:27
【问题描述】:

所以,首先,我已经查看了几个问题,包括 this one,但似乎都没有帮助。

我只是想写一个使用realloc()扩展数组大小的函数。

我的代码目前如下所示:

unsigned char *xtnd = malloc(4);
xtndc(&xtnd, 4);
// sizeof(*xtnd) should now be 8

void xtndc ( unsigned char ** bytesRef , uint8_t count ) {
    *bytesRef = realloc(*bytesRef, (sizeof(**bytesRef)) + count);
}

但无论我做什么,xtnd 的大小似乎始终为 4。在其上运行 xtndc() 后,它现在应该是 8 个字节长。

有什么建议吗?

【问题讨论】:

  • sizeof 没有给出数组的大小,只给出了指针本身。
  • @MichaelAlbers 这就是我取消引用它的原因?当我做sizeof(**bytesRef) 时,我取消引用取消引用的指针,对吗?我对 C 有点陌生,所以如果这不正确,请告诉我
  • 不,不是它是如何工作的。阅读:en.cppreference.com/w/c/language/sizeof
  • 您对sizeof 运算符有什么了解?如果 as 指针是一个数组,它会被称为“数组”,而不是“指针”
  • @Olaf 同样,我对 C 有点陌生。我的印象是,如果我将指针取消引用回到它的对象,我可以sizeof() 对象。现在我正在阅读sizeof()(感谢@MichaelAlbers),我发现它不是这样使用的。谢谢大家的帮助!

标签: c arrays realloc


【解决方案1】:

**bytesRef 的类型是unsigned char,所以sizeof(**bytesRef)1sizeof 不跟踪动态分配,它是一个编译时工具,可为您提供类型的大小,在本例中为 unsigned char

您必须手动跟踪数组大小以计算新的所需大小。

【讨论】:

    【解决方案2】:

    您的程序实际上确实改变了内存块的大小。它将原始内存块的大小从 4 个字节更改为 5 个字节。它变为 5 个字节,因为您实际上是在执行 sizeof(unsigned char) + 4 其中 1 + 4 = 5。如果您想将大小翻倍,请执行 count*sizeof(unsigned char) + count。这里有两点需要注意:

    1. sizeof 函数返回数据类型的大小,而不是分配字节的大小。没有办法知道动态分配的内存的大小。
    2. 函数realloc(以及malloccalloc)并不总是保证返回请求的重新分配。它可能会也可能不会一直成功。

    【讨论】:

      【解决方案3】:

      我用下面的代码解决了这个问题。

      typedef struct CArrPtr {
          unsigned char* ptr;
          size_t size;
      } CArrPtr;
      void xtndc ( CArrPtr *bytesRef, uint8_t count );
      
      . . .    
      
      CArrPtr xtnd = { .ptr = malloc(4), .size = 4 };
      xtndc( &xtnd, 4 );
      // xtnd.size is now 8 bytes 
      
      . . . 
      
      void xtndc ( CArrPtr *bytesRef, uint8_t count ) {
          unsigned char *nptr;
          if((nptr = realloc(bytesRef->ptr, bytesRef->size + count)) != 0) 
          {
              bytesRef->ptr = nptr;
              bytesRef->size = bytesRef->size + count;
          }
      }
      

      由于我对 C 有点陌生,因此我从中学到的是 malloc 专门创建了一个指向内存块的指针,但您无法直接访问有关内存块的信息。相反,您还必须将使用 malloc 创建的数组的大小存储在某处。

      由于过去我一直使用unsigned char arr[size]; 初始化数组,然后在其上使用sizeof,我的印象是sizeof 返回了数组的大小,这当然是错误的,因为它给出你一个类型的大小。

      很高兴我能从中学到一些东西。

      【讨论】:

      • 但是你必须调用你的函数来进行重新分配,然后进行算术运算。你的目标应该是设计你的代码,这样你就不需要那种工作分工。例如,您可能有一个保持指针和当前长度的结构类型,并且您会将指向该结构的指针传递给xtndc() 函数,以便该函数可以更新当前长度。另请注意,如果重新分配失败,old_ptr = realloc(old_ptr, new_size); 会泄漏内存。您应该使用:if ((new_ptr = realloc(old_ptr, new_size)) != 0) old_ptr = new_ptr; 或该主题的变体。不是测试。
      • @JonathanLeffler 感谢您的建议!我已经用他们更新了固定代码,它似乎可以工作,希望它达到标准:)
      • 对我来说看起来更好。如果你只使用一次,可能会大材小用,但如果你用得更多,它会减少每次编写的代码量。
      【解决方案4】:
      1. sizeof 用于计算数据类型或数组的大小。指针和数组非常相似,但它们是不同的东西。对于int *apsizeof(ap) 将在 x86 上返回 4,sizeof(*ap) 将返回 4;对于int a[10]sizeof(a) 将返回 40。

      2. sizeof表达式是在编译时处理的,所以在你运行程序之前它会是一个常量写入到可执行文件中。

      3. mallocrealloc 不保持大小。

      4. 如果realloc 成功,它将重新分配请求的大小。所以realloc返回后不需要检查大小,但要检查realloc的返回值,保证realloc成功。

      【讨论】:

        猜你喜欢
        • 2012-10-01
        • 1970-01-01
        • 2014-04-09
        • 2016-03-27
        • 2012-09-19
        • 1970-01-01
        • 1970-01-01
        • 2015-04-03
        • 2020-03-27
        相关资源
        最近更新 更多