尝试取消分配2d阵列时访问冲突读取

时间:2013-08-21 21:14:43

标签: c memory memory-management memory-leaks

我正在尝试释放使用以下代码分配的第二个数组:

int** createMatrix(int k)
{
    int i;
    int **res;

    res = (int**)malloc(sizeof(int*)*k);
    checkalloc(res);

    for (i = 0; i < k; i++)
    {
        res[i] = (int*)malloc(sizeof(int)*k);
        checkalloc(res[i]);
    }
    return res;
}

使用以下功能

void freeMatrix(int ***matrix, int k)
{
    int i;

    for (i = 0; i < k; i++)
        free(matrix[i]);

    free(matrix);
}

第一个元素正在被释放,但当i=1函数崩溃时出现错误:

First-chance exception at 0x0f7e7e2c (msvcr100d.dll) in Q2.exe: 0xC0000005: Access violation reading location 0xccccccc8.
Unhandled exception at 0x0f7e7e2c (msvcr100d.dll) in Q2.exe: 0xC0000005: Access violation reading location 0xccccccc8.

我做错了什么?

编辑:

当我尝试释放由:

分配的类似数组时,我也发生了同样的事情
CHARS** createImageMatrix(FILE *fp, int rows, int cols, int format)
{
    CHARS**res;
    int i;

    res = (CHARS**)malloc(sizeof(CHARS*)*rows);
    checkalloc(res);

    for (i = 0; i < height; i++)
    {
        res[i] = (CHARS*)malloc(sizeof(CHARS)*cols);
        checkalloc(res[i]);
    }
    return res;
}

并取消分配:

void freeCharsMatrix(CHARS **matrix, int rows)
{
    int i;
    for (i = 0; i < rows; i++)
        free(matrix[i]);
    free(matrix);
}

当CHARS为:

typedef struct Chars {
char A;
char B;
char C;
char D;

} CHARS;

但是这次我得到了:

error

我怎么了?

2 个答案:

答案 0 :(得分:4)

void freeMatrix(int ***matrix, int k)

==>

void freeMatrix(int **matrix, int k)

编辑:

free(matrix+i) // when you do this the pointer across the whole array . 

==&GT;

free(matrix[i])

答案 1 :(得分:1)

“ImageMatrix”示例存在两个主要问题:

  1. 您的createImageMatrix()函数未返回值。
  2. freeCharsMatrix()函数使用free(matrix+i)free(matrix[i])时调用free(*(matrix+i))
  3. 您的附属问题与编译有关:

    1. createImageMatrix()不使用fpformat参数。
    2. 该函数的正文用heightwidth编写,但参数为rowscols
    3. 以下是代码的调试版本。我已将freeCharsMatrix()重命名为freeImageMatrix(),因此名称更加一致。当我进行主要测试时,func_name引用拼写为__func__,但这是C99功能(即使使用-std=c89 -pedantic也允许GCC 4.8.1),所以我重命名了变量提供明确的定义,因为您最有可能使用C89编译器(MSVC仅支持23年的标准,而不是13年的标准或1年的标准)。

      您可以看到我最终如何诊断问题 - 打印传递给free()的地址,并将它们与malloc()返回的地址进行比较。我花了很长时间才发现matrix[i]相当于*(matrix+i)而不是matrix+i

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      
      typedef struct Chars
      {
          char A;
          char B;
          char C;
          char D;
      } CHARS;
      
      void dumpImageMatrix(CHARS **matrix, int rows, int cols);
      CHARS **createImageMatrix(int height, int width);
      void freeImageMatrix(CHARS **matrix, int height);
      
      static void dump_address(const char *tag, int num, void *vp)
      {
          printf("%s[%d] = %p\n", tag, num, vp);
      }
      
      static void checkalloc(void *vp)
      {
          if (vp == 0)
          {
              fprintf(stderr, "Memory allocation failed\n");
              exit(1);
          }
      }
      
      CHARS **createImageMatrix(int height, int width)
      {
          static const char func_name[] = "createImageMatrix";
          CHARS **res;
          int i;
      
          printf("-->> %s()\n", func_name);
          res = (CHARS**)malloc(sizeof(CHARS*)*height);
          checkalloc(res);
          dump_address("MTX", 0, res);
      
          for (i = 0; i < height; i++)
          {
              int j;
              res[i] = (CHARS*)malloc(sizeof(CHARS)*width);
              checkalloc(res[i]);
              dump_address("Row", i, res[i]);
              for (j = 0; j < width; j++)
                  memset(&res[i][j], (i + j) % 26 + 'A', sizeof(CHARS));
          }
          printf("<<-- %s()\n", func_name);
          return res;
      }
      
      void freeImageMatrix(CHARS **matrix, int height)
      {
          static const char func_name[] = "freeImageMatrix";
          int i;
          printf("-->> %s()\n", func_name);
          for (i = 0; i < height; i++)
          {
              dump_address("Row", i, matrix[i]);
              /*dump_address("CHK", i, matrix+i);*/
              /*dump_address("CHK", i, *(matrix+i));*/
              /*free(matrix[i]);*/
              free(*(matrix+i));
              /*free(matrix+i);*/
          }
          dump_address("MTX", 0, matrix);
          free(matrix);
          printf("<<-- %s()\n", func_name);
      }
      
      int main(void)
      {
          enum { m_rows = 5, m_cols = 6 };
          CHARS **mat = createImageMatrix(m_rows, m_cols);
          dumpImageMatrix(mat, m_rows, m_cols);
          freeImageMatrix(mat, m_rows);
          return 0;
      }
      
      static void dump_Chars(CHARS c)
      {
          printf("%c%c%c%c", c.A, c.B, c.C, c.D);
      }
      
      void dumpImageMatrix(CHARS **matrix, int rows, int cols)
      {
          static const char func_name[] = "dumpImageMatrix";
          int i;
          printf("-->> %s()\n", func_name);
          dump_address("MTX", 0, matrix);
          for (i = 0; i < rows; i++)
          {
              int j;
              dump_address("Row", i, matrix[i]);
              for (j = 0; j < cols; j++)
              {
                  if (j != 0)
                      putchar(' ');
                  dump_Chars(matrix[i][j]);
              }
              putchar('\n');
          }
          printf("<<-- %s()\n", func_name);
      }
      

      示例输出:

      -->> createImageMatrix()
      MTX[0] = 0x7f97cb4039d0
      Row[0] = 0x7f97cb403a00
      Row[1] = 0x7f97cb403a20
      Row[2] = 0x7f97cb403a40
      Row[3] = 0x7f97cb403a60
      Row[4] = 0x7f97cb403a80
      <<-- createImageMatrix()
      -->> dumpImageMatrix()
      MTX[0] = 0x7f97cb4039d0
      Row[0] = 0x7f97cb403a00
      AAAA BBBB CCCC DDDD EEEE FFFF
      Row[1] = 0x7f97cb403a20
      BBBB CCCC DDDD EEEE FFFF GGGG
      Row[2] = 0x7f97cb403a40
      CCCC DDDD EEEE FFFF GGGG HHHH
      Row[3] = 0x7f97cb403a60
      DDDD EEEE FFFF GGGG HHHH IIII
      Row[4] = 0x7f97cb403a80
      EEEE FFFF GGGG HHHH IIII JJJJ
      <<-- dumpImageMatrix()
      -->> freeImageMatrix()
      Row[0] = 0x7f97cb403a00
      Row[1] = 0x7f97cb403a20
      Row[2] = 0x7f97cb403a40
      Row[3] = 0x7f97cb403a60
      Row[4] = 0x7f97cb403a80
      MTX[0] = 0x7f97cb4039d0
      <<-- freeImageMatrix()