【问题标题】:Can't free memory from 2D dynamical array无法从 2D 动态数组中释放内存
【发布时间】:2016-04-05 09:12:26
【问题描述】:

我在释放内存时遇到问题。我这样做了很多次,而且效果很好。现在,它只是停止工作(没有错误,任何东西,只是冻结)。

我的代码是什么样子的:

void args(int argc, char** argv, int *n, int *m, int **matrix, char name[20])
{
int firstIter = TRUE;
int x;
char op;
int** second;

second = NULL;

op = argv[1][0];

for (x = 2; x < argc; x++)
{
    if (!firstIter)
    {
        setName(name, argv[x]);
        loadMatrix(*m, *n, second, *name);
        opMatrix(*m, *n, matrix, second, &*matrix, op);
    }
    else
    {
        setName(name, argv[x]);
        loadSizeMatrix(n, m, name);

        matrix = (int **)malloc(*n * sizeof(int*));
        for (int i = 0; i < *n; i++) {
            matrix[i] = (int *)malloc(*m * sizeof(int));
        }

        second = (int **)malloc(*n * sizeof(int*));
        for (int i = 0; i < *n; i++) {
            second[i] = (int *)malloc(*m * sizeof(int));
        }

        loadMatrix(*m, *n, matrix, *name);
        firstIter = FALSE;
    }
}

printMatrix(*m, *n, matrix);

for (int i = 0; i < *n; i++) {
    free(second[i]);
}

free(second[0]); //doesnt work too, and yes, there are data

free(second);
}

秒是这样填充的(loadMatrix):

for (int c = 0; c < radky; c++) {
        for (int d = 0; d < sloupce; d++) {
            fscanf(fp, "%i", &second[c][d]);
            // printf("%i", matice[c][d]); // dump
        }
    }

我该如何解决这个错误?

我的完整代码

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <ctype.h> //tolower
#include <string.h>

#define TRUE 1
#define FALSE !TRUE

/* konstanty */
const enum {
    MAX_DELKA_SOUBORU = 10000,
    MAX_SOUBOR = 20
}; 

const enum {
    SOUBOR_NENALEZEN = 1,
    SPATNE_ARGUMENTY = 2,
    LIMIT_NAZEV_SOUBOR = 3,
    SPATNY_OP = 4
};

void error(int type);
void zpracovaniArgumentu(int argc, char** argv, char(*nazevSouboru)[MAX_SOUBOR], char(*nazevVystupni)[MAX_SOUBOR], int *n, int *m, int **matice);
void setNazevSouboru(char(*nazev)[MAX_SOUBOR], char *argument);
void vypisMatice(int radky, int sloupce, int **matice);
int nacteniMaticeZeSouboru(int radky, int sloupce, int **matice, char nazev[MAX_SOUBOR]);
int nacteniVelikostiMatice(int *n, int *m, char nazev[MAX_SOUBOR]);
int operaceMatic(int radky, int sloupce, int **prvni, int **druha, int **vysledek, char op);

int main(int argc, char** argv)
{
    int n, m; // n = sloupce, m = radky pro prvni matici
    int** first;
    char nazevSouboru[MAX_SOUBOR], nazevVystupni[MAX_SOUBOR];
    char op;

    first = NULL;

    zpracovaniArgumentu(argc, argv, &nazevSouboru, &nazevVystupni, &n, &m, &*first);

    /* for (int i = 0; i < m; i++) {
        free(first[i]);
    } */
    free(first);

    system("pause");
    return 0;
}

void error(int type)
{
    switch (type) 
    {
    case SOUBOR_NENALEZEN:  printf("Soubor nenalezen!");
        break;
    case SPATNE_ARGUMENTY:  printf("Program spustte s argumenty [nazev souboru] *[nazev vystupniho souboru]*.\n");
        break;
    case MAX_DELKA_SOUBORU: printf("Prekrocen maximalni limit delky nazvu souboru (%i).\n", MAX_SOUBOR);
        break;
    case SPATNY_OP:         printf("Program spustte s argumenty [nazev souboru] *[nazev vystupniho souboru]*.\n");
        break;
    default:                printf("Nastala chyba!");
        break;
    }
    system("pause");
    exit(type);
}


void zpracovaniArgumentu(int argc, char** argv, char(*nazevSouboru)[MAX_SOUBOR], char(*nazevVystupni)[MAX_SOUBOR], int *n, int *m, int **matice)
{
    int firstIter = TRUE;
    int doSouboru = FALSE;
    int x;
    char op;
    int** second;

    second = NULL;

    op = argv[1][0];

    for (x = 2; x < argc; x++)
    {
        if (!firstIter)
        {
            setNazevSouboru(nazevSouboru, argv[x]);
            nacteniMaticeZeSouboru(*m, *n, &*second, *nazevSouboru);
            operaceMatic(*m, *n, matice, &*second, &*matice, op);
        }
        else if (argv[x][0] == '-')
        {
            switch (argv[x][1])
            {
            case 'n':   doSouboru = TRUE;
                break;
            default:    error(SPATNE_ARGUMENTY);
                break;
            }
        }
        else if (doSouboru)
        {
            setNazevSouboru(nazevVystupni, argv[x]);
        }
        else
        {
            setNazevSouboru(nazevSouboru, argv[x]);
            nacteniVelikostiMatice(n, m, *nazevSouboru);

            matice = (int **)malloc(*n * sizeof(int*));
            for (int i = 0; i < *n; i++) {
                matice[i] = (int *)malloc(*m * sizeof(int));
            }

            second = (int **)malloc(*n * sizeof(int*));
            for (int i = 0; i < *n; i++) {
                second[i] = (int *)malloc(*m * sizeof(int));
            }

            nacteniMaticeZeSouboru(*m, *n, &*matice, *nazevSouboru);
            firstIter = FALSE;
        }
    }

    vypisMatice(*m, *n, matice);

    for (int i = 0; i < *n; i++) {
        printf("%i",second[i]);
        free(second[i]);
    }

    free(second);
}


void setNazevSouboru(char(*nazev)[MAX_SOUBOR], char *argument)
{
    strcpy(*nazev, argument);
    strcat(*nazev, ".txt"); //nazev souboru
}

int nacteniVelikostiMatice(int *n, int *m, char nazev[MAX_SOUBOR]) 
{
    FILE *fp = fopen(nazev, "r"); // načtení souboru
    int c;
    int radky = 1;
    int sloupce = 0;
    if (!fp) 
    {
        error(SOUBOR_NENALEZEN);
        exit(2);
    }
    else 
    {
        while ((c = fgetc(fp)) != EOF) 
        {
            //tolower(c);
            if (c == '\n') 
            {
                radky++;
            }
            else if ((isdigit(c)) && (radky == 1)) 
            {
                sloupce++;
            }
        }
    }
    fclose(fp);
    *n = sloupce;
    *m = radky;
    return 0;
}

int nacteniMaticeZeSouboru(int radky, int sloupce, int **matice, char nazev[MAX_SOUBOR]) 
{
    int x;

    FILE *fp = fopen(nazev, "r"); // načtení souboru
    if (!fp)
    {
        error(SOUBOR_NENALEZEN);
        exit(2);
    }
    else
    {
        for (int c = 0; c < radky; c++) {
            for (int d = 0; d < sloupce; d++) {
                fscanf(fp, "%i", &matice[c][d]);
                // printf("%i", matice[c][d]); // dump
            }
        }
    }
    fclose(fp);
    return 0;
}

int operaceMatic(int radky, int sloupce, int **prvni, int **druha, int **vysledek, char op)
{
    int vysledekClip[10][10];

    for (int c = 0; c < radky; c++) {
        for (int d = 0; d < sloupce; d++) {
            switch (op) {
                case '+':   vysledekClip[c][d] = prvni[c][d] + druha[c][d];
                            vysledek[c][d] = vysledekClip[c][d]; 
                            break;
                case '-':   vysledekClip[c][d] = prvni[c][d] - druha[c][d];
                            vysledek[c][d] = vysledekClip[c][d];
                            break;
                case '/':   vysledekClip[c][d] = prvni[c][d] / druha[c][d];
                            vysledek[c][d] = vysledekClip[c][d];
                            break;
                case '%':   vysledekClip[c][d] = prvni[c][d] % druha[c][d];
                            vysledek[c][d] = vysledekClip[c][d];
                            break;
                case '*':   vysledekClip[c][d] = prvni[c][d] * druha[c][d];
                            vysledek[c][d] = vysledekClip[c][d];
                            break;
                default:    error(SPATNY_OP);
                            break;
            }
            vysledek[c][d] = vysledekClip[c][d];
        }
    }

    return 0;
}

void vypisMatice(int radky, int sloupce, int **matice)
{
    int c;
    int d;
    for (c = 0; c < radky; c++) {
        for (d = 0; d < sloupce; d++) {
            printf("%i\t", matice[c][d]);
        } printf("\n");
    }
}

void vypisMaticeDoSouboru(int radky, int sloupce, int **matice, char nazevSouboru[MAX_DELKA_SOUBORU])
{
    int c;
    int d;
    for (c = 0; c < radky; c++) {
        for (d = 0; d < sloupce; d++) {
            printf("%i\t", matice[c][d]);
        } printf("\n");
    }
}

【问题讨论】:

  • 您还需要什么?分配(在代码中)然后free(second[1]); 也被破坏了,任何地方......
  • 我添加了填充矩阵的函数。对你有用吗?
  • “我这样做了很多次,效果很好”请详细说明
  • 你确定 radky 和 ​​sloupce 的大小与 *n 和 *m 一样吗?
  • @DannyRuijters 我将这些值作为函数的参数发送,所以是的。如果我尝试free(second[1]) 之类的东西,它也会掉下来。打印矩阵的相同值 (n,m) 可以正常工作。

标签: c multidimensional-array free dynamic-memory-allocation


【解决方案1】:

“第二个”数组有问题。您分配一个 *n 指向 int 指针的数组,但在该数组中填充 *m 元素:

    second = (int **) malloc(*n * sizeof(int*));<p>
    for (int i = 0; i < *m; i++) {

【讨论】:

  • 这是一个很好的观察,你是对的,但它并没有解决我的问题:(正如我告诉它,当我尝试释放 second[0] 时它也会冻结(并且其中有数据)
  • 尝试记录所有分配和释放的指针。我将打印 malloc() 返回并传递给 free() 的每个指针(在调用 free() 之前)。可能是您在 second[] 中存在内存损坏,并且 free() 在释放未知指针时冻结
  • 我前面有“printMatrix”,如果我把“第二个”矩阵放在那里,它会打印正确的值。
  • 我尝试打印指针(不是它们的值)并且有一些内存地址
  • 非常抱歉,我运行这个应用程序没有问题。它既不会崩溃也不会卡住。
猜你喜欢
  • 1970-01-01
  • 2013-01-27
  • 2015-06-17
  • 2017-11-02
  • 1970-01-01
  • 2012-11-01
  • 2013-09-02
  • 2017-06-04
  • 2015-04-15
相关资源
最近更新 更多