簡體   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