C语言指针使用malloc的问题

最近在回顾C语言知识点时发现自己对指针的使用有些生疏了,把遇到的问题记录下来,以加深对指针的理解。

首先看下面的示例,实现将字符串反转输出,如“abcdef”, 输出为“fedcba”, 实现起来是不是很简单?
一开始我也这样觉得,下面是我第一次实现的代码:
int main(void)
{
    char *src = "Hello, World";
    char *dest = NULL;
    int len = 0;

    len = strlen(src);
    dest = (char *)malloc(len+1);
    if (dest == NULL) {
        printf("dest malloc failed.\n");
        return 0;
    }

    while (len-- != 0) {
        *dest++ = src[len];
    }

    *dest = 0;

    printf(“Sting dest: %s\n”, dest);
    free(dest);

    return 0;
}

看起开没问题,使用gcc -o test test.c也顺利编译通过了,但执行./test时发现竟然报错了,错误如下:
*** Error in `./test_bak': munmap_chunk(): invalid pointer: 0x00000000023f201c ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f931d8317e5]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x1a8)[0x7f931d83e698]
./test_bak[0x40068e]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f931d7da830]
./test_bak[0x400529]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:01 1325569                            /home/lipf/works/C_Project/lesson/lesson_1/test_bak
00600000-00601000 r--p 00000000 08:01 1325569                            /home/lipf/works/C_Project/lesson/lesson_1/test_bak
00601000-00602000 rw-p 00001000 08:01 1325569                            /home/lipf/works/C_Project/lesson/lesson_1/test_bak
023f2000-02413000 rw-p 00000000 00:00 0                                  [heap]
7f931d5a4000-7f931d5ba000 r-xp 00000000 08:01 1444647                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7f931d5ba000-7f931d7b9000 ---p 00016000 08:01 1444647                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7f931d7b9000-7f931d7ba000 rw-p 00015000 08:01 1444647                    /lib/x86_64-linux-gnu/libgcc_s.so.1
跟踪代码发现时free(dest)时报了“invalid pointer: 0x00000000023f201c ”的错误,当时有点不太理解为什么会报这样的错误,malloc分配也成功了,没理由会报非法指针的错误。先把free()这里屏蔽掉,看看结果是否如预期的那样,结果发现打印的dest为空,这是为什么呢?
进一步添加printf打印信息,如下:
    while (len-- != 0) {
        printf("dest point addr: %p\n", dest);
        *dest++ = src[len];
        printf("src char: %c\n", src[len]);
        printf("dest char: %c\n", *dest);
    }
将dest的地址以及存放的值打印出来,结果如下:
dest point addr: 0xdb2010
src char: d
dest char:
dest point addr: 0xdb2011
src char: l
dest char:
dest point addr: 0xdb2012
src char: r
dest char:
dest point addr: 0xdb2013
src char: o
dest char:
dest point addr: 0xdb2014
src char: W
dest char:
dest point addr: 0xdb2015
src char:  
dest char:
dest point addr: 0xdb2016
src char: ,
dest char:
dest point addr: 0xdb2017
src char: o
dest char:
dest point addr: 0xdb2018
src char: l
dest char:
dest point addr: 0xdb2019
src char: l
dest char:
dest point addr: 0xdb201a
src char: e
dest char:
dest point addr: 0xdb201b
src char: H
dest char:
String dest:

从打印的log可看出dest的值在改变,这里就涉及到了使用malloc()函数分配内存的问题,malloc返回的是分配内存的首地址,所以使用free释放内存时也应该是一开始分配的内存首地址,而示例中执行了*dest++,导致dest的值发生了变化,所以在执行free(dest)时会报错。
那要如何修正错误呢?下面提供了两种方法。
方法一:dest指针使用数组的形式
    int i=0;

    while (len-- != 0) {
        dest[i] = src[len];
        i++;
    }

    dest[len] = '\0';

    printf("dest String: %s\n", dest);
    free(dest);

方法二:使用指针
    dest = (char *)malloc(len + 1);
    char *tmp = dest;

    while (len-- != 0) {
        *tmp++ = src[len];
    }

    *tmp = '\0';

    printf("dest String: %s\n", dest);
    free(dest);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值