繁体   English   中英

结构中二维数组的免费 Memory

[英]Free Memory of 2d Array in struct

我正在 C 写一个小游戏,我想用 Valgrind 测试它。 这是一个小代码示例:

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

typedef struct Game {
    int** field;
} Game;

void buildfield(Game* game, int length);
void printfield(Game* game, int length);
void freefield(Game* game, int length);

int main()
{
    struct Game* game = NULL;
    game = malloc(sizeof (struct Game));
    buildfield(game, 10);
    printfield(game, 10);
    freefield(game, 10);
    free(game);
    return 0;
}

void buildfield(Game* game, int length)
{
    game->field = (int**)malloc((sizeof (int*)) * 20);
    int i;
    for (i = 0; i < 20; i++) {
        game->field[i] = (int*) malloc((sizeof (int)) * length);
    }

    for (int line = 0; line < length; line++) {
        for (int col = 0; col < 81; col++) {
            game->field[col][line] = 0;
        }
    }
}

void printfield(Game* game, int length)
{
    for (int i = 0; i < length; i++) {
        printf("\n");
        for (int j = 0; j < 20; j++) {
            printf("%d",game->field[i][j]);
        }
    }
}

void freefield(Game* game, int length)
{
    for (int i = 0; i < length; ++i) {
        free(game->field[i]);
    }
    free(game->field);
}

Valgrind 说:

HEAP SUMMARY:
==6239==     in use at exit: 968 bytes in 22 blocks
==6239==   total heap usage: 22 allocs, 0 frees, 968 bytes allocated

为什么我不释放分配?

那么在 function buildfield() 你已经分配了 20 个块 memory

game->field = (int **) malloc(sizeof(int *) * 20);

因此,您最多可以通过 [] 运算符访问 game->field[19] 但是在循环中,程序会尝试在 game->field[19] 之前访问更多块,从而导致分段错误并且程序会在那里崩溃。 无需返回 main(),更不用说到达 free() 语句了。 所以这意味着你的程序一开始就没有完成并且中途崩溃了。

for (int line = 0; line < length; line++)
{
    for (int col = 0; col < 81; col++)  //when col becomes 20
    {
        game->field[col][line] = 0;     //this statement will try to access the non-alloted memory block when col is 20
    }
}

要检查您的程序是否中途崩溃,请在与访问 memory 相关的语句末尾添加一些打印语句或使用调试器。 因为这是最常见的运行时错误来源。

同样对于此代码,请记住最大编号。 分配的 memory 个块中,可以由特定指针访问,并更改标记的 for 循环的条件,以便它将在分配限制内访问 memory,即第 2 个。 您使用 malloc function 分配的块数。

这里的问题不是 free() 不工作。 但是分段错误。 假设您提供的代码是您的代码的精确副本

“为什么我不释放分配?”

如评论中所述,由于使用无法解释的值( 幻数)创建和释放 memory,导致代码更加复杂。由于链接中解释的原因,除其他问题外,这可以使匹配的释放计数与计数分配困难。 由于 Valgrind 指示在执行结束时剩余的 memory 块,因此调用这些中的每一个的时间不匹配。

以下是您的代码和建议,包括那些明确应用与[m][c]alloc()相同数量的调用free()的代码(我选择在此处使用calloc()以避免另一个循环(或memset() ) 来初始化 memory。)

另请注意,您可能需要更改此示例用于 #defines 的值以满足您的需要,但您只需在一个地方(在文件顶部)更改它们。

typedef struct Game {
    int** field;
} Game;

void buildfield(Game *game, int length);
void printfield(Game *game, int length);
void freefield(Game *game, int length);

#define COUNT  20//replace all magic numbers 
#define LENGTH 10//(change values of #defines to change shape and size of memory)

int main(void)//use a complete prototype for main
{
    struct Game* game = NULL;//pointer needs memory
    game = malloc(sizeof (struct Game));

    buildfield(game, LENGTH);
    printfield(game, LENGTH);
    freefield(game, LENGTH);
    free(game);
    return 0;
}

void buildfield(Game *game, int length)
{   //Note - not optimal to cast return of [c][m]alloc in C (only in C++)
    game->field = calloc(COUNT, sizeof(game->field));
    int i;
    for (i = 0; i < COUNT; i++) {
        game->field[i] = calloc(LENGTH, (sizeof (game->field[i])) );
    }
}

void printfield(Game *game,int length)
{
    for (int i = 0; i < COUNT; i++) {
        printf("\n");
        for (int j = 0; j < LENGTH; j++) {
            printf("%d",game->field[i][j]);
        }
    }
}

void freefield(Game *game,int length)
{
    for (int i = 0; i < COUNT; ++i) {
        free(game->field[i]);
    }
    free(game->field);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM