内存泄漏/管理建议(方法中的新数组)(c ++)

时间:2015-08-10 01:55:01

标签: c++ memory-management memory-leaks

我正在关注youtube上的教程并尝试在文件中稍微更改代码输入法:

static std::string read_file(const char* filepath){
    FILE* file = fopen(filepath, "rt");     //read text file
    fseek(file, 0, SEEK_END);
    unsigned long length = ftell(file);
    char* data = new char[length + 1];
    memset(data, 0, length + 1);
    fseek(file, 0, SEEK_SET);
    fread(data, 1, length, file);
    fclose(file);

    std::string result(data);
    delete[] data;
    return result;
}

这是原始代码,它将在此上下文中使用:

std::string vertSourceString = read_file(m_VertPath);
const char *source = vertSourceString.c_str();

所以我想"为什么我要使用String?我必须包含它,然后我必须将eveything复制到字符串,以便我可以将它再次复制到char *?所以我尝试了这个:

static char* read_file(const char* filepath){
    FILE* file = fopen(filepath, "rt");     //read text file
    fseek(file, 0, SEEK_END);
    unsigned long length = ftell(file);
    char* data = new char[length + 1];
    memset(data, 0, length + 1);
    fseek(file, 0, SEEK_SET);
    fread(data, 1, length, file);
    fclose(file);

    return data;
}

但是如果我不删除它,那么这会有非常明显的内存泄漏:

char *c = read_file("src/shaders/basic.vert");
delete c;

那么,有没有办法在方法中删除它并仍然返回它的副本? 对于需要删除的方法来说,这似乎不是一种好习惯。 我应该回到之前的实施吗?

PS:我知道c ++有一个更容易的"阅读文件的方式(fstream),但是来自一项小型研究(我承认,我没有经过任何测试)这种方式通常更快

2 个答案:

答案 0 :(得分:0)

您可以使用std::stringstd::ifstreamstd::ostringstream重写此内容,如下所示:

#include <string>
#include <sstream>
#include <fstream>

static std::string read_file(const std::string& filepath)
{
    std::ostringstream oss;
    oss << std::ifstream(filepath, std::ios::binary).rdbuf();
    return oss.str();
}

或者,这种方法可以通过削减“中间人”来提高效率(但不那么优雅)。 (std::ostringstream):

static std::string read_file2(const std::string& filepath)
{
    std::ifstream ifs(filepath, std::ios::binary|std::ios::ate);

    std::string buf;
    buf.resize(ifs.tellg());
    ifs.seekg(0);

    if(ifs.read(&buf[0], buf.size()))
        return buf;

    return {};
}

注意:这里的第二种方法是我使用std::ostringstreamstd::FILE* fp = fopen()&amp; posix int fd = open()

答案 1 :(得分:0)

动态内存分配由程序员在C ++中管理。 然后,问题是,除非你事先知道文件的大小,否则在方法之外分配一个缓冲区,然后传递它。 类似的东西:

inodes

然后在read_file中:

dosomething(file, file_size) {
char a[file_size]; //a is a pointer.
read_file(file, a);
}

通过执行类似的操作,您不必手动为char内容释放内存,因为它的堆栈内存,并且在退出作用域时会自动释放。

然后,这种方法再次需要您知道文件大小。