无法从struct成员变量中释放内存

时间:2018-01-26 19:47:47

标签: c

在C中的结构变量上调用free之后,然后检查该变量是否为NULL,它向我显示它是非NULL。所以free没有用?我的代码:

struct main_struct {
    struct my_file *file;
};

struct my_file {
    char *host;
    int port; // this cannot be malloc'ed and free'ed
};

struct my_file* read_file() {
    FILE *f;
    struct my_file *file;

    //open FILE for reading..

    file = malloc(sizeof(struct my_file)); //allocate memory for my_file struct
    memset(file, 0, sizeof(struct my_file));

    // while loop to read file content..
    // in the loop:
        char *value = line;
        file->host = malloc(sizeof(char) * strlen(value)); //allocate memory for host member variable
        strncpy(file->host, value, strlen(value)); //assign value to host variable

    return file;
}

int main() {
    struct main_struct *mstr;
    mstr = malloc(sizeof(struct main_struct)); //allocate memory to main_struct
    memset(mstr, 0, sizeof(struct main_struct));

    mstr->my_file = read_file(); //call to read file, allocate mem for my_file struct and the 'host' member variable

    // some code

    // call free here:
    if(mstr->my_file->host != NULL) {
        free(mstr->my_file->host);
    }
    // check if mem has been freed:
    if(mstr->my_file->host == NULL) {
        printf("mstr->my_file->host is NULL, good.\n");
    } else {
        printf("mstr->my_file->host is NOT NULL, bad.\n"); // I see this.
    }

    // I also try to free mstr->my_file:
    if(mstr->my_file != NULL) {
        free(mstr->my_file);
    }
    // check if mem has been freed:
    if(mstr->my_file == NULL) {
        printf("mstr->my_file is NULL, good.\n");
    } else {
        printf("mstr->my_file is NOT NULL, bad.\n"); // I see this.
    }

    // and also mstr itself..
}

我是否正确使用free函数,因为我已经看到了free被调用的示例: free(&mystruct->myfile->host);通过将指针的地址发送给free。但我认为现在我自由呼叫的方式是正确的。?

2 个答案:

答案 0 :(得分:4)

free(x)没有自动设置x没有NULL,它只是释放内存并让x指向无效位置。如果您想免费x,可以使用

这样的功能
void clear(void** ptr) { free(*ptr); *ptr = NULL; }

...

free(&(mstr->my_file->host));

或者你每次都可以手动完成。逗号运算符可以在这里提供帮助:

mstr->my_file->host = (free(mstr->my_file->host), NULL);

编辑:如果您正好使用glib(及其内存管理包装器),可以使用g_clear_pointerg_clear_object来帮助解决此问题。

答案 1 :(得分:2)

free(&foo)总是错的。您只能free / malloc / calloc(以及realloc等包装器)返回的strdup指针值。 &foo是现有变量的地址(由编译器管理)。

free(ptr)不会将ptr设置为NULL。通常,函数调用f(x)不能修改x,因为C按值传递参数。它只会释放ptr后面的内存,而不会触及ptr本身。

free(ptr)有点特殊情况,因为之后ptr的值是不确定的,这意味着您的if(mstr->my_file->host != NULL)检查实际上有未定义的行为(查看不确定的值不是允许的)。

另见http://c-faq.com/malloc/ptrafterfree.html

随机评论:

  • 切勿使用strncpy。它不是一个字符串函数(在某种意义上它不能使用或生成C字符串),它的行为会在某些时候咬你。

  • 乘以sizeof (char)毫无意义:根据定义,sizeof (char)为1。

  • malloc + memset可以通过使用calloc来组合以获得零初始化内存。 (在某些情况下,calloc也比malloc / memset快得多。)