C++ 字符数组分配错误

Posted

技术标签:

【中文标题】C++ 字符数组分配错误【英文标题】:C++ character array allocation error 【发布时间】:2010-12-04 08:29:19 【问题描述】:

我有一个用来获取文件内容的函数:

bool getFileContents(std::string loc, std::string &code) 
    std::ifstream file(loc.c_str());

    if(!file.is_open())
        return err("Source file could not be read");

    int length;
    file.seekg(0, std::ios::end);
    length = file.tellg();
    file.seekg(0, std::ios::beg);

    char *buffer = new char[length];
    file.read(buffer, length);
    code = buffer;
    delete[] buffer;

    file.close();

    return true;

当我运行这个函数时,文件的长度总是被准确地检索到。但是,如果我用一个文件调用该函数一次,用一个不存在的文件再次调用它,然后用原始文件再调用一次,字符串'buffer'大于int'length'。

嗯,这可能不准确,而是 - 当字符串 'buffer' 复制到字符串 'code' 时,'code' 比 'length' 长。在每个实例中,'code' 都在调用 'getFileContents' 之前立即实例化,因此它不是先前值的问题。

如果我检索文件的内容,随后从文件中添加或删除一些文本,然后再次检索相同文件的内容,这似乎也会发生。

我对字符串几乎没有经验,并且认为我没有正确使用它们,但我使用的代码来自一个示例,我一生都找不到它有什么问题。

感谢您的帮助, 悦

【问题讨论】:

你不熟悉异常吗?看起来您正在通过调用一个报告错误的函数来处理错误,该函数始终返回 false,因此您可以使用返回值来传播异常,同时强制调用者创建一个输出参数。这是令人难以置信的倒退。使用return 返回值。使用异常来报告异常事件(例如文件在应有的情况下不存在)。 例外有什么好处?我不会为其他任何人构建此代码,并且拥有一个全局错误字符串几乎不会妨碍我的工作。我更喜欢这种方法,它集中了错误处理,并且比 try/catch 块更简洁。 你不能只使用'code'变量并将内容从文件读取复制到它(毕竟,你是通过引用传递参数)? 【参考方案1】:

嗯,问题是code = buffer 依赖一个 NUL (\0) 字符来知道缓冲区的结束位置。有时您可能会偶然获得 NUL 字符(尤其是在程序刚刚启动时),但并非总是如此。因此出现间歇性行为。

尝试将code = buffer 替换为code = std::string(buffer, length)

【讨论】:

为了避免不必要的分配,最好使用code.assign(buffer, buffer+length) Doc Brown,如果文件中包含 \0 怎么办?【参考方案2】:

除了 aix 描述的 \0 问题之外,您会执行双重分配,这在此处是不必要且不安全的(在 delete 之前可能是一个例外,并且您将拥有内存泄漏)。相反,您可以在字符串内部分配缓冲区,如下所示:

code.resize(length);
file.read(&code[0], length);

别忘了检查read 的返回值。不能保证一步读取所有length 字节。

【讨论】:

以上是关于C++ 字符数组分配错误的主要内容,如果未能解决你的问题,请参考以下文章

C++如何用new动态开辟一个一维字符数组

c++中字符串是如何分配内存的?

从数组分配值时字符数组编译时错误

在字符串和结构数组中查找动态内存分配错误

在 C++ 中返回字符串数组

“字符串”数组的动态分配[重复]