简单的动态内存分配错误

时间:2010-05-08 10:26:02

标签: c pointers memory-management malloc dynamic-memory-allocation

我确信你(专业人员)可以在我的代码中识别错误',我也很感激我的代码上的任何其他评论。

BTW,运行后代码崩溃了。

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

typedef struct
{
    int x;
    int y;
}  Location;

typedef struct
{
    bool walkable;
    unsigned char walked; // number of times walked upon
} Cell;

typedef struct
{
    char name[40];  // Name of maze
    Cell **grid;    // 2D array of cells
    int rows;       // Number of rows
    int cols;       // Number of columns
    Location entrance;
} Maze;


Maze *maz_new()
{
    int i = 0;

    Maze *mazPtr = (Maze *)malloc(sizeof (Maze));

    if(!mazPtr)
    {
        puts("The memory couldn't be initilised, Press ENTER to exit");
        getchar();
        exit(-1);
    }
    else
    {
        // allocating memory for the grid
    mazPtr->grid = (Cell **) malloc((sizeof (Cell)) * (mazPtr->rows));

    for(i = 0; i < mazPtr->rows; i++)
        mazPtr->grid[i] = (Cell *) malloc((sizeof (Cell)) * (mazPtr->cols));
    }

    return mazPtr;
}


void maz_delete(Maze *maz)
{
    int i = 0;

    if (maz != NULL)
        {
            for(i = 0; i < maz->rows; i++)
                free(maz->grid[i]);

            free(maz->grid);
        }
}


int main()
{
    Maze *ptr = maz_new();
    maz_delete(ptr);

    getchar();
    return 0;
}

提前致谢。

3 个答案:

答案 0 :(得分:1)

除了马塞洛指出的问题,我发现了这一点:

mazPtr->grid = (Cell **) malloc((sizeof (Cell)) * (mazPtr->rows));

您正在分配10个单元格,这会返回指向第一个单元格的指针,该单元格的类型为Cell *Cell结构是boolunsigned char,根据编译器和目标体系结构,它可能不会被分配得足够大以容纳Cell *(可能是64位指针)。稍后初始化网格数组时,最终可能会写出数组的末尾。

因此,尝试在网格中分配10 sizeof (Cell *)。并解决当然的初始化问题。

答案 1 :(得分:0)

迷宫应该有多大?您永远不会初始化rowscols

但是,最大的问题是,在初始化grid时使用sizeof(Cell),但它应该是sizeof(Cell *)。

在我的架构上,Cell只有两个字节,而Cell *是八个字节,这意味着你没有分配足够的空间。当你填写这个数组时,你正在写出结束并进入其他一些已分配的内存,此时所有的赌注都会关闭。内存分配器在某些时候破坏了数组的内容,你就会试图释放垃圾。

答案 2 :(得分:0)

在maz_delete中你需要另一个免费调用maz结构本身

void maz_delete(Maze * maz)    {      int i = 0;

 if (maz != NULL)
 {
     for(i = 0; i < maz->rows; i++)
         free(maz->grid[i]);

     free(maz->grid);

     free(maz);
 }

}