调用释放已存储值的 char 指针时,free() 函数失败

Posted

技术标签:

【中文标题】调用释放已存储值的 char 指针时,free() 函数失败【英文标题】:The free() function failed when calling out to free a char pointer that had stored a value 【发布时间】:2020-04-18 00:08:59 【问题描述】:

我正在学习有关 C 编程语言中动态内存分配的知识。当我试图编写如下描述的程序时:

编写一个名为 duplicate 的函数,该函数使用动态存储分配来创建字符串的副本。比如调用

p = 重复(str);

会为一个与 str 长度相同的字符串分配空间,将 str 的内容复制到新字符串中,并返回一个指向它的指针。如果内存分配失败,则重复返回一个空指针。

这是《C Programming Language, A Modern Approaches(2nd ver.)》一书第17章的练习2。

在我的第一次尝试中,我编写了如下代码:

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

char *duplicate(char* str)
    char* news=(char*)malloc((strlen(str)+1)*sizeof(char));
    if(news==NULL)
        printf("Error: malloc failed\n");
        return NULL;
    
    strcpy(news,str);
    return news;


int main()
    char *str,*p;
    str="Hello world";
    p=duplicate(str);
    puts(p);
    
    return 0;

成功运行。 但是当我修改我的代码调用 free(str) 如下:

int main()
    char *str,*p;
    str="Hello world";
    p=duplicate(str);
    free(str);
    puts(p);
    return 0;

它没有任何输出就失败并返回一个正常值。 在我的书中,它没有提到任何关于这个问题的内容,只是给出了一些关于 free() 函数的例子,该函数在没有分配任何值的指针上使用。我很好奇我的代码有什么问题?如果我想使用 free 函数,使用它的正确方法是什么?如何释放指向已分配某个值的内存的指针?

【问题讨论】:

您不能通过free() 获取不是从malloc()(或calloc()realloc())获得的东西。在你想要的程序中:p = duplicate(str); puts(p); free(p); 你可以free(p)。你不能(也不需要)免费str OT:在C语言中不需要转换void-pointers,例如返回我的malloc() 如果duplicate()失败,代码不应该调用puts(),如果它返回NULL会说。 执行if (news == NULL) printf("Error: malloc failed\n"); else strcpy(news, str); return news; 会更简单,更不容易出错。它也遵循了很好的模式,每个函数只有 一个 退出点。 【参考方案1】:

指令

str="Hello world";

将常量字符串“Hello world”分配给str。它不会为带有malloc 的字符串分配存储空间。所以你不能用str 作为参数调用free。只有使用malloc 获得的指针才能传递给free

“Hello world”是存储在程序特殊位置的常量字符串。你不能释放它并修改它。

【讨论】:

那个特殊的位置在哪里?

以上是关于调用释放已存储值的 char 指针时,free() 函数失败的主要内容,如果未能解决你的问题,请参考以下文章

在指针上调用 free 两次

C语言中free函数的用法

在 free() 之后将指针设置为 NULL 总是一个好习惯吗? [复制]

求助 一个指针被free之后啥时候是NULL?还是不可能是NULL?

[C]安全释放堆内存

释放指针后真的应该将指针设置为“NULL”吗?