这是为数组数组分配内存的好方法吗? (C)

时间:2014-02-25 17:02:01

标签: c malloc free

好吧,想象一下我有一个char**,这是分配内存的正确方法吗? 我的意思是:为char**本身分配内存,然后为每个char* ...

分配内存
char** fraseUsuario = NULL;
int length = 100, i = 0;

fraseUsuario = (char **) malloc(sizeof (char*)); //Not pretty sure

for (i = 0; i < 3; i++) {

    fraseUsuario[i] = (char *) malloc(length * sizeof (char));

    if (fraseUsuario[i] == NULL) {
        printf("error\n");
        return -1;
    }

    gets(fraseUsuario[i]);

}

for (i = 0; i < 3; i++) {
    printf("%s\n",  fraseUsuario[i]);
    free(fraseUsuario[i]);
}

顺便问一下,free()究竟是如何工作的?我的意思是,当我在最后调用它时,使用调试器看起来似乎“没有”,如果“Hello”存储在数组中,它将在free调用后继续存储在那里。 ..这是正常的行为吗?

2 个答案:

答案 0 :(得分:1)

你是什么意思allocate memory for the char **本身?在定义变量时,可以为堆栈上的变量分配内存。以下语句定义(分配内存)fraserUsuario并将其初始化为NULL

char **fraseUsuario = NULL;

我认为你可能意味着如何动态分配char **数组,即指向字符指针的指针。然后再次为先前分配的数组的每个元素动态分配一个数组。 请勿使用gets 。它已被弃用且使用不安全。请改用fgets。另外,请不要投射malloc的结果。您没有获得任何好处,如果您忘记包含包含其原型的标题stdlib.h,则可能会遇到错误。这是你如何做到的。

char **fraseUsuario = NULL;
int max_string_len = 100 + 1;  // maximum string length. +1 for null byte
int num_string = 3;            // number of strings to read
int i, j;

fraseUsuario = malloc(num_string * sizeof *fraseUsuario);
if(fraseUsuario == NULL) {     // check for NULL
    // handle the case
    printf("not enough memory\n");
    return -1;
}

for(i = 0; i < num_string; i++) {
    fraseUsuario[i] = malloc(max_string_len * sizeof(char));
    if(fraseUsuario[i] == NULL) {     // check for NULL
        printf("not enough memory\n");
        for(j = 0; j < i; j++)
            free(fraseUsuario[j]);    // free memory before returning
        free(fraseUsuario);           // free memory before returning
        return -1;
    }
    if(fgets(fraserUsuario[i], max_string_len, stdin) == NULL) {
        // reading string failed
        *fraserUsuario[i] = '\0'; // empty string
    }
}

for(i = 0; i < 3; i++) {
    printf("%s\n", fraseUsuario[i]);
    free(fraseUsuario[i]);    // free memory allocated for strings
}
free(fraseUsuario);           // free memory allocated for pointers to strings 
fraseUsuario = NULL;   

当您通过调用free调用的内存地址上调用malloc时,内存块将返回到堆上的空闲池。然后,malloc可以重用此内存块。一旦你free记忆,你就放弃了对它的所有权。它不再属于并且尝试使用它是非法的,并且会导致未定义的行为和可能的段错误。

答案 1 :(得分:0)

您只为一个 char*分配内存,但使用三个

要解决此问题,请执行以下操作:

#define STR_MAXIMUM (3)

...

size_t length = 100, i = 0; /* No need to use a signed type. 
                               size_t is meant as index and size type. */
char ** fraseUsuario = malloc(STR_MAXIMUM * sizeof(*fraseUsuario)); 

for (i = 0; i < STR_MAXIMUM; ++i) 
{
  fraseUsuario[i] = malloc(length * sizeof(*fraseUsuario));

    ...

还要为系统调用添加错误检查。


另外^ 2: Do not use gets() 因为编译器或机器无法防止传入的缓冲区溢出。 Use fgets() instead

    fgets(fraseUsuario[i], length, stdin);