C - 包含字符串的表的动态内存分配

时间:2016-04-13 08:06:34

标签: c memory memory-management out-of-memory heap-memory

我尝试动态地为包含字符串的表进行内存分配 在我的情况下,我必须动态使用它,因为我不知道程序将获得的行和列 这是我的两个功能的代码:
1.第一种是仅为表格分配内存 2.第二个应该释放所有分配的内存 3.在主函数中,我为字符串分配内存并复制预定义字符串的一部分(例如,它只是虚拟代码)

结果是“运行时错误” 我在代码中做错了什么?

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

char *** buildOptions(int rows, int columns) {
    int i=0;
    printf("1...\n");
    char ***options = (char ***)malloc(rows * sizeof(char **));
    printf("2...\n");
    for(i=0; i<rows; i++) {
        printf("3...\n");
        options[i] = (char **)malloc(columns * sizeof(char *));
        printf("4...\n");
    }
    return options;
}

void freeOptions(char ****options, int rows, int columns) {
    int i, j;
    for(i=0; i<rows; i++) {
        for(j=0; j<columns; j++) {
            if(*options[i][j])
                free(*options[i][j]);
        }
        if(*options[i]) {
            free(*options[i]);
        }
    }
    free(*options);
}

int main(void) {
    int i, j, k;
    char * str = "123456789abcdefghjkl\0";
    char ***options = buildOptions(5, 3);
    printf("Starting...\n");
    for(i=0; i<5; i++) {
        for(j=0; j<3; j++) {
            options[i][j] = (char *)calloc((i+j+2)+1, sizeof(char));
            strncpy(options[i][j], str, i+j+2);
        }
    }

    for(i=0; i<5; i++) {
        for(j=0; j<3; j++) {
            printf(">>options[%d][%d]=%s<<\n", i,j, options[i][j]);
        }
    }

    freeOptions(&options, 5, 3);

    //here I want to check if the memory is freed
    for(i=0; i<5; i++) {
        for(j=0; j<3; j++) {
            printf(">>options[%d][%d]=%s<<\n", i,j, options[i][j]);
        }
    }


    return 0;
}

2 个答案:

答案 0 :(得分:2)

freeOptions 的声明更改为

void freeOptions(char ***options, int rows, int columns)

的呼吁
 freeOptions(options, 5, 3);

并在 freeOptions 中调用 free()

  free(options[i][j]);

答案 1 :(得分:0)

分段错误的原因在于您在freeOptions中访问数组的方式:

*options[i][j]

与:

相同
*(options[i][j])

僵尸options is the address of your选项in主要, so you should dereference选项`首先:

(*options)[i][j]

除非您打算在char ***options中将main设置为*options,否则实际上无需通过引用从NULL传递freeOptions。迈克尔的另一个答案已经指出了实施freeOptions的更好方法。

//here I want to check if the memory is freed

您无法通过访问现在无效的内存并导致未定义的行为来确定free是否已成功。数据可能仍然存在,但它可能包含垃圾。