像这样使用malloc是对的吗?

时间:2017-06-22 16:23:48

标签: c malloc free

我是动态内存分配的新手。 这种类型的使用是否会造成任何内存泄漏或未分配的内存访问?

char *func2(char *str) {
    //Do something like writing 10 characters to str
    return str;
}

void func1() {
    char *str = NULL, *res;
    int len = 10;
    str = (char *)malloc(len * sizeof(char));
    res = func2(str);
    free(str); 
    printf("%s", res);
}

func1中的最终printf语句是否会导致分段错误,因为str已被释放,res是否为悬空指针,没有内存位置指向?

2 个答案:

答案 0 :(得分:2)

在引用的内存被释放后使用

res。这是未定义的行为,可能会也可能不会导致运行时错误。毕竟,未定义的行为是未定义的。

在实践中,我认为可能会发生的是,您的程序会愉快地打印内存res点中的内容。记忆没有消失,你刚才说你不再使用它了。在那段记忆中将会是未初始化的垃圾,因为你从来没有写过任何东西。我想你会得到gobbledygook输出。

答案 1 :(得分:1)

是的,这是一个错误。我们可以通过将代码转换为工作示例并在Valgrind下运行它来证明错误:

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

char *func2(char *str)
{
    strcpy(str, "hello!");
    return str;
}

int main()
{
    char *str, *res;
    int len = 10;
    str = malloc(len);
    res = func2(str);
    free(str);
    printf("%s", res);
}

输出显示了发生的事情:

gcc -std=c11 -fPIC -g -Wall -Wextra -Wwrite-strings -Wno-parentheses -Wpedantic -Warray-bounds      44704791.c    -o 44704791
valgrind --leak-check=full ./44704791 
==12624== Memcheck, a memory error detector
==12624== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==12624== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==12624== Command: ./44704791
==12624== 
==12624== Invalid read of size 1
==12624==    at 0x4C2EDA2: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12624==    by 0x4E80D77: vfprintf (vfprintf.c:1637)
==12624==    by 0x4E871F8: printf (printf.c:33)
==12624==    by 0x1087B5: main (44704791.c:18)
==12624==  Address 0x51d7040 is 0 bytes inside a block of size 10 free'd
==12624==    at 0x4C2CDDB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12624==    by 0x10879D: main (44704791.c:17)
==12624==  Block was alloc'd at
==12624==    at 0x4C2BBAF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12624==    by 0x10877D: main (44704791.c:15)

它向我们显示第18行的printf试图从第17行释放的内存中读取。此外,它显示有问题的内存是在第15行分配的。

故事的寓意是你应该在你完成使用它之后释放内存(而不是之前),如果你不清楚你的函数是否取得了指针传递给它们的内存的所有权,那么这很难做到。