0

I'm sure you (pros) can identify the bug's' in my code, I also would appreciate any other comments on my code.

BTW, the code crashes after I run it.

#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;
}

Thanks in advance.

4

3 に答える 3

1

マルセロが指摘した問題に加えて、私はこれを発見しました:

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

10個のセルを割り当てています。これにより、タイプが最初のセルへのポインタが返されますCell *Cell構造体はaとbool、であり、コンパイラとターゲットアーキテクチャによっては、 (64ビットポインタの場合もあります)unsigned charを保持するのに十分な大きさに割り当てられない場合があります。Cell *後でグリッド配列を初期化するとき、おそらく配列の終わりを超えて書き込むことになります。

sizeof (Cell *)したがって、グリッドに10を割り当ててみてください。もちろん、そこで初期化の問題を修正します。

于 2010-05-08T11:27:11.047 に答える
0

迷路の大きさはどれくらいですか?初期化することはありませrowscols

ただし、大きな問題は、初期化時にsizeof(Cell)を使用することですが、gridsizeof(Cell *)である必要があります。

私のアーキテクチャでCellは、は2バイトだけですが、Cell *は8バイトです。これは、十分なスペースが割り当てられていないことを意味します。この配列に入力すると、最後を超えて、割り当てられたメモリの他のチャンクに書き込みが行われ、その時点ですべての賭けが無効になります。メモリアロケータは、ある時点で配列の内容を破壊し、ゴミを解放しようとします。

于 2010-05-08T10:42:52.667 に答える
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);
 }

}

于 2014-12-03T13:06:49.550 に答える