我是动态内存分配的新手。 这种类型的使用是否会造成任何内存泄漏或未分配的内存访问?
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
是否为悬空指针,没有内存位置指向?
答案 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行分配的。
故事的寓意是你应该在你完成使用它之后释放内存(而不是之前),如果你不清楚你的函数是否取得了指针传递给它们的内存的所有权,那么这很难做到。