字符串内存分配中可能存在内存泄漏
Posted
技术标签:
【中文标题】字符串内存分配中可能存在内存泄漏【英文标题】:Possible memory leak in string memory allocation 【发布时间】:2014-03-23 09:10:00 【问题描述】:这是我的代码:
#include <string>
#include <iostream>
#include <cstdio>
#include <cstdlib>
std::string & fileread(const char * name)
FILE *fp = fopen(name,"rb");
size_t sz;
int i;
char *buff;
fseek(fp, 0, SEEK_END);
sz = ftell(fp);
fseek(fp, 0, SEEK_SET);
buff = (char *)malloc(sizeof(char)*(sz+1));
buff[sz] = '\0';
fread(buff,sz,1,fp);
std::string * rtstr = new std::string(buff);
free(buff);
fclose(fp);
return * rtstr;
int main(int argc,char * argv[])
std::string file_info(fileread(argv[1]));
std::cout<<file_info << std::endl;
return 0;
它只是读取一个文件,并将其内容打印到屏幕上。
在函数fileread
中,我使用new std::string(buff);
得到std::string *
,并将点返回。会不会导致内存泄漏?如果答案是“是”,如何避免呢?
关于在 C++ 中使用 C:fread
比 ifstream
快得多(用 10 亿个随机数测试)
我的问题是关于内存泄漏。
【问题讨论】:
不要在 C++ 中编码 C。使用std::ifstream
和std::string
(不是std::string*
)。
fread()
与std::ifstream::read()
一样快。再说一次,不要认为 C 在性能方面会获胜。 C++ 也同样出色,并且在某些情况下,性能优于 C。
@Nawaz 请分享一些“比 C 性能更好”的好链接。
@SahilSareen C++ 类型系统鼓励静态类型检查和值语义,这两者都能带来更好的优化。例如,考虑std::sort()
与qsort()
:C 基于函数指针(CPU 管道的最大敌人之一),另一方面,C++ 基于模板和仿函数(也就是编译器内联所有内容)。跨度>
@SahilSareen:将使用指针(通常为void*
和函数指针)的任何代码通用 C 代码与使用模板的通用 C++ 代码进行比较。 C++ 最有可能比 C 更快。一个这样的例子是 std::sort
(来自 C++ 标准库)与 qsort
(来自 C 标准库)。
【参考方案1】:
按值返回 std::string。别担心,C++ 会注意不冗余地复制对象(除非你有一个非常旧的编译器)。 这是代码,已修复:
#include <string>
#include <iostream>
#include <cstdio>
#include <cstdlib>
std::string fileread(const char * name)
FILE *fp = fopen(name,"rb");
size_t sz;
int i;
char *buff;
fseek(fp, 0, SEEK_END);
sz = ftell(fp);
fseek(fp, 0, SEEK_SET);
buff = (char *)malloc(sizeof(char)*(sz+1));
buff[sz] = '\0';
fread(buff,sz,1,fp);
std::string rtstr(buff);
free(buff);
fclose(fp);
return * rtstr;
int main(int argc,char * argv[])
std::string file_info(fileread(argv[1]));
std::cout<<file_info << std::endl;
return 0;
我只做了必要的小改动,忽略了您的代码中可能遇到的任何其他问题。保重。
【讨论】:
[yu@argcv ex]$ g++ test.cc --std=c++11 test.cc: In function ‘std::string fileread(const char*)’: test.cc:22:12: error: no match for ‘operator*’ (operand type is ‘std::string aka std::basic_string<char>’) return * rtstr; ^
如果只返回rtstr,则返回一个本地值。
@YuJing:它返回一个副本,而不是对局部变量的引用。
@Nawaz 和,我可能会从文件中读取 1GB 或更多 binary
数据,请您提供更多更好的建议吗?
return * rtstr;
行需要替换为return rtstr;
任何现代编译器都会执行返回值优化,因此不会进行复制。【参考方案2】:
正如 Nawaz 正确评论的那样:“不要在 C++ 中编写 C 代码。使用 std::ifstream 和 std::string(不是 std::string*)”。这是避免所有问题的 C++ 代码:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main ()
string line;
ifstream myfile ("myfile.txt");
if (myfile.is_open())
while ( getline (myfile,line) )
cout << line << '\n';
myfile.close();
else cout << "Unable to open file";
return 0;
【讨论】:
请注意,您不必使用myfile.close()
。此外,if (myfile)
优于 if (myfile.is_open())
。
@Nawaz 我用它来正确关闭它。这样做不是一个好习惯吗?
当流对象超出范围时,它将关闭文件。它是 RAII 对象。所以不用担心。
@SahilSareen:请参阅 my question on Code Review 关于这个确切问题。
std::getline
如果他打算读取二进制数据,可能不适合以上是关于字符串内存分配中可能存在内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章