【问题标题】:2d array of struct -- malloc() and free()二维结构数组——malloc() 和 free()
【发布时间】:2013-01-17 13:04:31
【问题描述】:
#pragma pack(push, 1)
typedef struct 
{
      /*...*/
  unsigned int      dataoffset;         //No of bytes before actual pixel data
}HEADER;

typedef struct 
{
   /*...*/
   unsigned int     width;
   unsigned int     height;
   unsigned short   bits_per_pixel;         //code is written for 24 bits only and No other format is supported..
    /*...*/
}INFO_HEADER;

typedef struct 
{
   unsigned char    b;
   unsigned char    g;
   unsigned char    r;        
}COLORMAP;

#pragma pack(pop)


int main()
{
      // Var decl.
  INFO_HEADER       *pHeader = NULL;
  FILE              *pImage;
  COLORMAP          **ppColors;
  /*...*/

/* File opened in read, binary mode, memory allocated for pHeader*/     

fread (pHeader, sizeof(INFO_HEADER), 1, pImage);  

/*Next block is actually problematic.. Posting 'as is' from my code*/
      ppColors = (COLORMAP**)malloc((pHeader -> height ) * sizeof(COLORMAP));
  for(i = 0 ; i < pHeader -> height ; i++)
     ppColors[i] = (COLORMAP*)malloc(pHeader -> width * sizeof(COLORMAP));
fseek(pImage, pHeader -> fileheader.dataoffset, SEEK_SET);
    for (i = 0 ; i < pHeader -> width ; i++) 
  {
      for (j = 0 ; j < pHeader -> height ; j++) 
      {
          fread(&b, sizeof(unsigned char), 1, pImage);
          fread(&g, sizeof(unsigned char), 1, pImage);
          fread(&r, sizeof(unsigned char), 1, pImage);

          ppColors[i][j].b = b;
          ppColors[i][j].g = g;
          ppColors[i][j].r = r; 

          printf("width = %d height = %d %d:\t", i, j,  cnt);
          printf("%d ", (int)ppColors[i][j].b);
          printf("%d ", (int)ppColors[i][j].g);
          printf("%d\n", (int)ppColors[i][j].r);
          cnt++;  
      }
  }

  /*And at last free()ing..*/
  for(i = 0 ; i < pHeader -> height ; i++)        free(ppColors[i]);
   free(ppColors);
  cleanup();
  return(0)
}

可能重复:http://stackoverflow.com/questions/1568042/optimal-way-to-free-a-malloced-2d-array-in-c

虽然上面的链接不能解决我的问题。

  1. 内存不足。我对高度进行了 malloc() 处理,然后对于每个高度,宽度再次进行了 malloc() 处理。我正在尝试仅在宽度 X 高度域上工作。看来问题出在身高上。如果你改变了

ppColors = (COLORMAP**)malloc((pHeader -&gt; height ) * sizeof(COLORMAP)); 到 ppColors = (COLORMAP**)malloc((pHeader -&gt; height + 6 ) * sizeof(COLORMAP));

然后这个问题就消失了。

  1. 但是在 free()ing 时,我在核心转储处得到双重释放/损坏。

我该死的肯定我在某个地方出错了。我不希望有人纠正我的代码,我只是运行它。只需提示即可。

【问题讨论】:

    标签: c multidimensional-array malloc free


    【解决方案1】:

    指向指针的指针不与数组数组相同。

    当使用指针来模拟多维数组时,像这样声明:

    char **pointer;
    

    内存是这样的:

    +------------+------------+------+------ --+ |指针[0] |指针[1] | ... |指针[大小 - 1] | +------------+------------+------+------ --+ | | | v v v 数据 数据 数据

    而适当的多维数组

    char array[X][Y];
    

    在内存中看起来像这样:

    +-------------+-------------+------+--------------- --+--------------+------+ |数组[0][0] |数组[0][1] | ... |数组[0][Y - 1] |数组[1][0] | ... | +-------------+-------------+------+--------------- --+--------------+------+

    所以在一个适当的多维数组中,所有内存都在一个块中,而使用指针到指针时,你有一个指针数组而不是数组数组。


    所以你应该做的是分别分配所有子数组:

    ppColors = malloc(pHeader->height * sizeof(COLORMAP *));
    /* Note how I allocate the width times the size of a COLORMAP pointer */
    
    for (int i = 0; i < pHeader->height; i++)
        ppColors[i] = malloc(pHeader->width * sizeof(COLORMAP));
    

    别忘了你现在也必须循环调用free!

    【讨论】:

      【解决方案2】:

      我可以看到几个问题:

      • ppColors 是一个指针数组。数组中的每个元素都是一个COLORMAP*,因此您需要使用numElements * sizeof(COLORMAP*) 计算要分配的大小。 COLORMAP 只有 3 个字符,所以很可能是 sizeof(COLORMAP*) > sizeof(COLORMAP)。您当前的分配将太小,因此您最终会写到数组末尾之外;这会产生不确定的影响,但可能会崩溃。
      • 在分配和循环之间使用的宽度和高度是相反的,因此您最终会在循环中的某个点写入未分配的内存。

      【讨论】:

      • 是的.. 问题是第一个要点。对于第二个项目符号 pt -> 抱歉,我在发布之前编辑了代码..并按“原样”发布..但我仍然不明白为什么 sizeof(COLORMAP*)..?你能详细说明一下吗..?
      • @Adorn 很高兴有帮助。我已经尝试更新我的答案。如果还不清楚,请告诉我。
      【解决方案3】:

      这可能不是一个答案,但可能会与其他答案一起帮助您。

      • 这可能是fread 的问题,检查您在pHeader -&gt; height 和pHeader -&gt; width 中得到了什么

      • 在malloc(pHeader -&gt; width * sizeof(COLORMAP)) 中使用括号括住pHeader -&gt; width

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-13
        • 2011-10-30
        • 2013-11-30
        • 2012-05-19
        • 1970-01-01
        • 2017-05-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多