V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
africwildman
V2EX  ›  C

C 语言 free()函数的问题

  •  
  •   africwildman · 2019-06-11 23:57:13 +08:00 · 3979 次点击
    这是一个创建于 1991 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如下代码:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        char *a=(char *)malloc(5*sizeof(char));
        char *b=(char *)malloc(5*sizeof(char));
        a="1234";
        b="5678";
        printf("%s\n",a);
        printf("%s\n",b);
        free(a);
        free(b);
        return 0;
    }
    

    运行时显示错误:free(): invalid pointer

    a 和 b 互不相干,为什么就 free 出问题了呢?

    19 条回复    2019-06-12 15:59:30 +08:00
    huaouo
        1
    huaouo  
       2019-06-12 00:00:17 +08:00 via Android   ❤️ 1
    因为 free 的不是 malloc 出来的堆上的地址,而是"1234", "5678"这两个字符串字面值的地址。
    Nitroethane
        2
    Nitroethane  
       2019-06-12 00:01:48 +08:00 via Android
    "1234" 和 "5678" 是字符串字面量,是保存在可执行二进制文件里面的
    byteli
        3
    byteli  
       2019-06-12 00:01:49 +08:00 via Android
    很久不写 c 猜测下,是 a= b=造成的隐式转换吧,要用*a= *b=
    creamiced
        4
    creamiced  
       2019-06-12 00:04:15 +08:00   ❤️ 1
    赋值方式有问题,可以使用类似 strcpy(a,"1234")
    a="1234"之后,a 已经不再指向 malloc 出来的内存,而是指向 1234 这个字符串常量的地址了
    africwildman
        5
    africwildman  
    OP
       2019-06-12 00:06:47 +08:00
    @huaouo
    @Nitroethane
    @creamiced
    哦,明白了,我赋值方式不对。
    PanPancf
        6
    PanPancf  
       2019-06-12 00:07:44 +08:00
    free 错了,还导致了 memory leak。。你的本意应该要 strcpy
    elfive
        7
    elfive  
       2019-06-12 06:37:12 +08:00 via iPhone
    对 char*的赋值就错了……你要用 strcpy 或 memcpy 去给它赋值成其他字符串的……
    tamlok
        8
    tamlok  
       2019-06-12 08:50:15 +08:00 via Android
    建议再认真看看 c 教材。。。
    zycpp
        9
    zycpp  
       2019-06-12 09:18:02 +08:00 via iPhone
    哈哈哈,跟我以前一样
    ps:sprintf 也能赋值字符串
    testeststs
        10
    testeststs  
       2019-06-12 10:18:00 +08:00
    a="1234";
    这个你不会以为是拷贝吧。
    haozhang
        11
    haozhang  
       2019-06-12 10:28:53 +08:00 via Android
    a="1234" 这一句就是错的,“ 1234 ”是 const char *,而 a 是 char *,按照理论上,你无法把一个 const char *赋值给 char *,你这个就编译不过去。
    haozhang
        12
    haozhang  
       2019-06-12 10:32:50 +08:00 via Android
    “ 1234 ”这个是字符串常量,存放在堆上面的,内存的开辟释放都是由汇编写死的,不需要你去 free,a=1234,相当于把 1234 的存放的内存地址赋值给 a,但这么做是非法的,因为 a 是 char*,1234 是由一个 const char *指向的,你无法把一个 const char *赋值给 char *变量
    zwh2698
        13
    zwh2698  
       2019-06-12 11:07:26 +08:00 via Android
    大侠,看到你的标题我吓到了,看到代码,我想说看看谭浩强的书,不用求人。
    skx926
        14
    skx926  
       2019-06-12 11:44:13 +08:00
    @haozhang 常量不应该在常量区吗,怎么会在堆上
    haozhang
        15
    haozhang  
       2019-06-12 12:10:05 +08:00 via Android
    @skx926 恩,是存在常量区,我说错了
    tomychen
        16
    tomychen  
       2019-06-12 13:06:01 +08:00
    @zwh2698 哈哈,,,我怎么觉得你这回复那么可爱
    oaix
        17
    oaix  
       2019-06-12 14:06:55 +08:00
    不要使用 strcpy,使用带长度参数的 strncpy
    wisefree
        18
    wisefree  
       2019-06-12 15:43:00 +08:00
    @haozhang 题主问的是 C 语言,不是 C++

    ``` c
    #include <stdio.h>

    int main(void)
    {
    char *s = NULL;
    s = "1234"; // C 语言中不会报错
    printf("%s\n", s);

    return 0;
    }

    ```
    haozhang
        19
    haozhang  
       2019-06-12 15:59:30 +08:00
    @wisefree c 也会报错的啊,c11 之后这个 char *str = “ 123 ”,就已经不能写了,c11 之前就算你写了有也不能用 str[0] = ’ 6 ’ 这种去修改 read only 的东西,会报 runtime error 的,你可以用版本高一点的 gcc 试试。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1865 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 16:20 · PVG 00:20 · LAX 08:20 · JFK 11:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.