我怎样才能确保我不会错过malloc和free中的某些内容?

时间:2017-08-19 12:48:50

标签: c malloc dynamic-allocation

char **test() {
    char **res = (char **)malloc(sizeof(char *) * 5);
    for (int cur = 0; cur < 3; cur++) {
        char *str = (char *)malloc(10);
        strcpy(str, "Maneger");
        res[cur] = (char *)malloc(strlen(str));
        strcpy(res[cur], str);
        free(str);
    }
    res[3] = NULL;
    return res;
}

int main(int argc, char *argv[]) {
    char **li = test();
    //some code
    free(li);
    return 1;
}

上述代码中的free()有什么问题。这是对的吗?

3 个答案:

答案 0 :(得分:1)

您忘记为终止空字符分配空间。

该行

res[cur]=(char *)malloc(strlen(str));

应该是

res[cur]=(char *)malloc(strlen(str) + 1);

还应添加检查malloc()不是NULL的返回值。

答案 1 :(得分:1)

主要免费是不正确的。它只释放分配给li指针的内存而不释放分配给与之关联的指针数组的内存。

释放li指针后,分配给与之关联的指针数组的内存将变得无法访问,这是错误的。

释放所有内存的正确方法如下:

free(li[0]);
free(li[1]);
free(li[2]);

在这些陈述之后应该有:

free(li);

希望它会有所帮助!!

答案 2 :(得分:0)

您的代码中存在多个问题:

  • 为什么要为5个指针分配空间,但只使用4?
  • 为什么要为str分配10个字节,将字符串复制到它,复制它并为每次迭代释放str?
  • 您不会在"Maneger"
  • 的副本中为空终止符分配空格
  • 您没有释放li中的字符串。
  • 您不会检查潜在的malloc失败。

以下是更正后的版本:

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

void free_test(char **a) {
    if (a) {
        for (int i = 0; a[i]; i++) {
            free(a[i]);
        }
        free(a);
    }
}

char **test(void) {
    char **res = malloc(sizeof(*res) * 4);
    if (res) {
        int cur;
        for (cur = 0; cur < 3; cur++) {
            res[cur] = strdup("Maneger");
            if (res[cur] == NULL) {
                free_test(res);
                return NULL;
            }
        }
        res[cur] = NULL;
    }
    return res;
}

int main(int argc, char *argv[]) {
    char **li = test();
    if (li == NULL)
        return 1;
    //some code
    free_test(li);
    return 0;
}

strdup()是一种更简单,更安全的复制字符串的方法。它不是标准C的一部分,但在Posix和其他系统上受支持。如果您的系统上没有它,可以通过以下方式重新定义:

char *strdup(const char *s) {
    size_t len = strlen(s);
    char *p = malloc(len + 1);
    if (p != NULL) {
        memcpy(p, s, len + 1);
    }
    return p;
}