c - 分配/重新分配内存的内存泄漏,“1 个块中的 5 个字节肯定丢失”
问题描述
检查我的程序是否存在内存泄漏时出现 valgrind 错误。分配/重新分配内存时,该错误发生在我的 cutString 函数中的某处,但我不确定我做错了什么。
我是否错误地分配了内存?
这是 valgrind 的输出:
$ valgrind --leak-check=full --track-origins=yes ./cutstring
==7017== Memcheck, a memory error detector
==7017== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==7017== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==7017== Command: ./cutstring
==7017==
Hell
==7017==
==7017== HEAP SUMMARY:
==7017== in use at exit: 5 bytes in 1 blocks
==7017== total heap usage: 3 allocs, 2 frees, 1,042 bytes allocated
==7017==
==7017== 5 bytes in 1 blocks are definitely lost in loss record 1 of 1
==7017== at 0x4839D7B: realloc (vg_replace_malloc.c:826)
==7017== by 0x109205: cutString (in cutstring)
==7017== by 0x109228: main (in cutstring)
==7017==
==7017== LEAK SUMMARY:
==7017== definitely lost: 5 bytes in 1 blocks
==7017== indirectly lost: 0 bytes in 0 blocks
==7017== possibly lost: 0 bytes in 0 blocks
==7017== still reachable: 0 bytes in 0 blocks
==7017== suppressed: 0 bytes in 0 blocks
==7017==
==7017== For counts of detected and suppressed errors, rerun with: -v
==7017== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
这是我的代码:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
char *cutString(char *str, char del)
{
char *new_string = (char*) malloc(strlen(str) * sizeof(char) + 1);
int i = 0;
while (str[i] != del)
{
new_string[i] = str[i];
i++;
}
new_string[i] = '\0';
new_string = (char*) realloc(new_string, strlen(new_string) + 1);
return new_string;
free(new_string);
}
int main()
{
printf("%s\n", cutString("Hello World!", 'o'));
return 0;
}
我猜我使用 realloc 不正确,但我不知道为什么。
一些帮助将不胜感激,谢谢!
解决方案
cutString
必须分配内存并返回它。当然(幸运的是),没有达到无条件之后的所有语句。return
return new_string;
free(new_string); // never executed
}
幸运的是!因为否则你会返回未分配的内存:未定义的行为。
这里的问题是您将返回的值传递给printf
,但在调用之后,指针丢失了。您必须存储它才能释放它,但只有在打印它之后。
int main()
{
char *s = cutString("Hello World!", 'o'));
printf("%s\n", s);
free(s);
return 0;
}
在 C 中,不可能在printf
不产生内存泄漏的情况下对分配内存的函数进行流水线化。其他语言有垃圾收集器或对象析构函数,但 C 没有。
推荐阅读
- python - 使用 S3FS 访问 TFX 管道中的 S3 存储桶对象
- laravel - npm run dev 不做任何拉动 - laravel
- ios - SwiftUI - 如何在编辑时删除列表左侧的巨大空间
- javascript - 数组重复值数量的正确结果
- javascript - async / await 函数和返回值
- nginx - 将非 2xx 请求的请求正文发送到 syslog nginx
- node.js - 使用 http-proxy-middleware NodeJS 在互联网上代理图像文件
- ftp - PhpStorm - FTP 错误日志位于何处?
- python - 如何从终端中的先前运行中获取变量值?
- amazon-web-services - 如何修复错误在使用 Amazon 的 S3 和 Cloudfront 时,请求的资源上不存在“Access-Control-Allow-Origin”标头