【问题标题】:realloc int pointer present in a structure [C]realloc int 指针存在于结构中 [C]
【发布时间】:2012-07-29 15:02:13
【问题描述】:

我想分配一个存在于结构中的整数指针。

如果将来我需要扩展数组,我会使用 realloc。

类似这样的:

typedef struct {
   int *temp,count
}foo;

main()
{
    foo *fake = (foo*)malloc(1*sizeof(foo));
    fake.count = 0;

    ++(fake.count);
    fake.temp = (int*)malloc((fake.count)*sizeof(int));

    /* I do something */

    /*now i want to realloc "temp" to ++(fake.count) */

这种做法正确吗?

    ++(fake.count);
    fake.temp = (int*)realloc(fake.temp,(fake.count)*sizeof(int));

【问题讨论】:

  • 应该是 fake->count fake->temp 等

标签: c structure realloc


【解决方案1】:

很难说在不知道I do something 是什么的情况下这样做realloc 是否OK。但是你可以从这个开始......

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

typedef struct {
 int *temp,count;
 }foo;

extern char etext, edata, end;
int main()
{
   printf("Heap before first malloc %p\n", sbrk(0));

   foo *fake = malloc(1*sizeof(foo));

   printf("heap after first malloc %p\n", sbrk(0));

   fake->count = 0;
   ++(fake->count);
   fake->temp = malloc((fake->count)*sizeof(int));
   printf("heap after second malloc %p\n", sbrk(0));

   fake->count += 2;
   fake->temp = realloc(fake->temp, (fake->count) * sizeof(int));
   printf("count %d\n", fake->count);

   printf("heap after realloc %p\n", sbrk(0));
   printf("program text segment(etext)      %10p\n", &etext);
   printf("initialized data segment(edata)  %10p\n", &edata);
   printf("uninitialized data segment (end) %10p\n", &end);

   return 0;
}

这也会输出你的堆地址。

Heap before first malloc 0x239b000
heap after first malloc 0x23bc000
heap after second malloc 0x23bc000
count 3
heap after realloc 0x23bc000
program text segment(etext)        0x400816
initialized data segment(edata)    0x600bc4
uninitialized data segment (end)   0x600bd8
  1. malloc() 不需要演员表。

  2. 考虑使用calloc() 清除您的记忆。在重新分配时,您可能会得到错误初始化的内存块。 (比如最近释放的块)。

  3. 在使用之前请务必检查realloc() 的返回值。 realloc() 失败的几率比 malloc() 高。

【讨论】:

    【解决方案2】:

    原则上是的。

    但是,您应该确保您的代码在realloc 中可能出现的错误中仍然存在,如下所示:

    int * p = realloc(fake->temp, (fake->count + 1) * sizeof(int));
    if (p) { fake->temp = p; ++fake->count; }
    else   { /* error! But fake was untouched. */ }
    

    另外,你应该为你的主函数声明说int main(void)。最后,您不应该转换 malloc 或 realloc 的结果,因为 void* 可以隐式转换为任何其他对象指针。

    还有一点:你的编码风格真的很难让别人读懂。我会这样写结构定义:

    typedef struct foo_
    {
        int * temp;
        int   count;
    } foo;
    

    还有一个:你需要动态分配fake吗?如果没有,自动变量foo fake; 可能更容易维护。无论如何,如果您确实想动态分配它,请不要强制转换并且不要重复类型,如下所示:

    foo * fake = malloc(sizeof *fake);
    // or:       calloc(1, sizeof *fake);      // this will zero out the memory
    

    【讨论】:

    • 感谢您的回复。你的意思是说我应该在你的情况下使用另一个指针“p”来重新分配“fake.temp”,然后如果重新分配成功,让“fake.temp”保持“p”的重新分配内存。如果我不这样做,比如使用另一个 int 指针,如果我尝试访问重新分配的内存或最初分配的内存,它会在将来给我分段错误吗??
    • @sam32: 不是分段错误,但realloc 的结果可能是NULL,如果立即覆盖原始指针,则永远无法再次到达原始分配。一旦realloc 返回一个非空指针,就可以安全地使用它了。
    • 我确实需要动态分配它。我并没有真正理解您的观点,即“不要投射,不要重复类型”。能否请您详细说明一下。谢谢!
    • @sam32:我的最后一行代码malloc 只包含类型的名称(即“foo”)一次,而不是您的代码中的三倍.而且没有演员表。
    【解决方案3】:
    1. 您无需在 C 程序中强制转换来自 malloc 或 realloc 的返回值。
    2. 不要将realloc 调用的结果直接分配给同一个变量。如果失败,您将泄漏原始分配。改为这样做:

      void *err = realloc(pointer, newSize);
      if (err != NULL)
      {
          pointer = err;
      }
      
    3. Nitpick - 乘以 1 看起来很奇怪。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-25
      • 2018-07-02
      • 2021-02-27
      • 1970-01-01
      • 2018-06-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多