写入文件时删除[]导致的分段错误

segmentation fault cause by delete[] while writing to a file

本文关键字:分段 错误 文件 删除      更新时间:2023-10-16

我正试图写入一个文件,当我删除分配的内存时,遇到了分段错误。我不知道问题出在哪里,请帮忙:

void writeToLog(string msg) {
    int len = msg.size()+1;
        char *text = new char(len);
    strcpy(text,msg.c_str());
    char* p = text;
    for(int i=0; i<len; i++){
        fputc(*p, _log) ;
        p++;
    }
    delete[] text;   //THIS IS WHERE IT CRASHES
}

我也尝试过不使用[ ],但后来我得到了*** glibc detected *** ./s: free(): invalid next size (fast): 0x09ef7308 ***

那么问题出在哪里呢?

谢谢!

这:

char *text = new char(len);

应该是:

char *text = new char[len + 1];

无论如何,这都是不必要的。你为什么这么做?

好吧,delete[]不平衡new char(N),它平衡new char[N]。前者创建一个指向单个char的指针,并赋予其值N;后者创建一个指向长度为Nchar数组的指针并保留这些值。

当然,要将std::string写入FILE *,为什么不直接这样做呢:

fwrite(msg.c_str(), sizeof(char), msg.size() + 1, _log);

注意,保留尾随的null字符;您的原始代码也是如此。

char *text = new char(len);

只分配一个字符。试用:

char *text = new char[len];

试试这个:

char *text = new char[len];

然后:

delete[] text;

尽管技术问题已经得到解决(new/delete对不匹配),但我仍然认为您可以从这里获得一些帮助。因此,我建议帮助您精简代码。

第一:如果您只是不执行复制,就不会有任何问题。

void writeToLog(string msg) {
    typedef std::string::const_iterator iterator;
    for(iterator it = msg.begin(), end = msg.end(); it != end; ++it) {
        fputc(*it, _log) ;
    }
}

请注意,我是如何重新编写代码以使用C++迭代器,而不是混合使用指针和索引的。

第二:这个fputc调用是什么?

您不应该在代码中使用FILE*。如果你这样做了,你很可能也会出错,忘记关闭它,或者关闭两次等等…

标准库提供了Streams集合来处理输入和输出,对于日志文件,ofstream类似乎特别适合。

std::ofstream _log("myLogFile");
void writeToLog(std::string const& msg) { // by reference (no copy)
  _log << msg;
}

注意它是如何简单得多的?你也不能忘记close这个文件,因为如果你忘记了,那么当_log被破坏时,它就会被关闭。

当然,在这一点上,人们可能会认为拥有一个功能是超级棒的。然而,这样的函数允许您为消息添加前缀,通常带有时间戳/PID/Thread ID或其他装饰,所以它仍然很好。