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.
精彩评论