开发者

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

I'm trying to write to a file and i get a segmentation fault when i delete the allocated memory. I don't understant what i开发者_如何转开发s the problem, please help:

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
}

I also tried without the [ ] but then i get *** glibc detected *** ./s: free(): invalid next size (fast): 0x09ef7308 ***

So what is the problem?

Thanks!


This:

char *text = new char(len);

should be:

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

And this is all unnecessary anyway. why are you doing it?


Well, delete[] doesn't balance new char(N), it balances new char[N]. The former creates a pointer to a single char and gives it the value N; the latter creates a pointer to an array of char with length N, and leaves the values indefined.

Of course, to write a std::string to a FILE *, why not just do:

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

Note that preserves the trailing null character; so does your original code.


char *text = new char(len);

allocates just one char. Try with:

char *text = new char[len];


Try this:

char *text = new char[len];

Then:

delete[] text;


Although the technical issue has been answer (mismatched new/delete pair), I still think you could benefit from some help here. And I thus propose to help you trim your code.

First: there would not be any issue if you simply did not perform a copy.

void writeToLog(string msg) {
    typedef std::string::const_iterator iterator;

    for(iterator it = msg.begin(), end = msg.end(); it != end; ++it) {
        fputc(*it, _log) ;
    }
}

Note how I reworked the code to use C++ iterators instead of a mix of pointers and indices.

Second: what is this fputc call ?

You should not need to use a FILE* in your code. If you do, you are likely to get it wrong too and forget to close it, or close it twice etc...

The Standard Library provides the Streams collection to handle input and output, and for a log file the ofstream class seems particularly adapted.

std::ofstream _log("myLogFile");

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

Note how it is much simpler ? And you cannot forget to close the file either, because if you do forget, then it'll be closed when _log is destructed anyway.

Of course at this point one might decide that it is superflous to have a function. However such a function allows you to prefix the message, typically with timestamps / PID / Thread ID or other decorations, so it's still nice.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜