struct的二维数组 - malloc()和free()

时间:2013-01-17 13:04:32

标签: c multidimensional-array malloc free

#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()ed为高度,然后对于每个高度,宽度再次是malloc()ed。我正在尝试仅在宽度X高度域上工作。看来这个问题与身高有关。如果你改变了
  2. ppColors = (COLORMAP**)malloc((pHeader -> height ) * sizeof(COLORMAP));ppColors = (COLORMAP**)malloc((pHeader -> height + 6 ) * sizeof(COLORMAP));

    然后这个问题就消失了。

    1. 但是在free()的时候,我在核心转储中获得双重免费/腐败。
    2. 我确定我在某个地方出错了。我不希望有人纠正我的代码,我只是运行它。只是暗示会做。

3 个答案:

答案 0 :(得分:3)

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

使用指针指向模拟多维数组时,如此声明:

char **pointer;

内存看起来像这样:

+------------+------------+-----+-------------------+
| pointer[0] | pointer[1] | ... | pointer[size - 1] |
+------------+------------+-----+-------------------+
     |            |                  |
     v            v                  v
   Data         Data               Data

虽然是一个合适的多维数组

char array[X][Y];

在内存中看起来像这样:

+-------------+-------------+-----+-----------------+-------------+-----+
| array[0][0] | array[0][1] | ... | array[0][Y - 1] | array[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

答案 1 :(得分:2)

我可以看到几个问题:

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

答案 2 :(得分:1)

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

  • fread检查pHeader -> heightpHeader -> width

  • 中的内容可能会出现问题
  • pHeader -> width

  • 中的malloc(pHeader -> width * sizeof(COLORMAP))周围使用括号