tale&operator+=(tale&text){
size_t len=text.length();
_buffer=(s_char*)realloc(_buffer,_length+len+1);
// should be _buffer=(s_char*)realloc(_buffer,len);
strcpy(&_buffer[_length],text.gets());
// strcat may be more suitable for the requirement.
_length+=len;
return*this;
};
@vlad - take it easy, I really don't see anything wrong with mixing malloc/realloc with objective code (as long as we work with raw buffers).
@Tomhet:
The problem is the last byte in original (it means before append) _buffer[] here.
1 2 3 4
//
// Because You call this function with the same object text.gets() means really _buffer.
//
strcpy(&_buffer[_length],text.gets()); // it means _buffer + _buffer in our case
There is one common byte to destination and source in strcpy.
Zero terminator at _buffer[len] is overwritten by the first appended char, so strcpy does not detect zero terminator in source string corretly.
The both operands represent the same object. So they have the same value of data member _buffer. You are calling realloc in the operator. So the value of _buffer for the right operand becomes invalid because the memory it pointed was freed. After that you are trying to access the memory that was freed.
take it easy, I really don't see anything wrong with mixing malloc/realloc with objective code.
Vlad's being rude and unpleasant, but he's also right. It's really not a great idea to mix your memory management models, as it can lead to all sorts of unnecessary confusion.
And for dynamically allocating objects, you need to use new (and delete), to ensure your constructors (and destructors) are called properly. So, much better to just use new and delete all the way through when writing C++.
I don't like to use string
Really? You like all the memory management headaches that come with continuing to use C-style char arrays? You like having to remember to worry about whether or not your strings are NULL-terminated? You like not having the easy-to-use richness of the methods on strings, and the support provided by STL?
Well, if that's the case, then I guess you must enjoy getting these kinds of bugs and crashes.
You are calling realloc in the operator. So the value of _buffer for the right operand becomes invalid because the memory it pointed was freed. After that you are trying to access the memory that was freed.
It's not true, because both source and destination in strcpy are after realloc.
@Tomhet: Problem is one common byte between original source and destination strings
(zero terminator in _buffer[len] is overwritten by the first appended char, so strcpy does not detect zero terminator corretly).
You don't need extra malloc/free or new/delete to solve it.
Did You try my code from few posts before?
Feel free to ask if something is still not understood.
Vlad from Moscov wrote:
(...) it is a stupid code.
1). Please tell me where did you read that memory for objects in C++ should be allocated with using malloc or realloc?!(...)
In any case you should use operator new and delete instead of malloc, realloc and free,
Little offtop about memory allocation - above tip it's not steal rule.
Until we're working with raw buffers we can still use malloc/free/realloc and it's still correct in C++ (even if uncommon) - @vlad: please don't messy up others in unpleasant way (Tomhet's problem wasn't related with using malloc).
More, for tasks like above (creating own string class) with potentially many reallocations and a lot of low-level work on raw buffers, malloc/realloc is one of the best choice. (Do we really need initialization from new, when we're going to fill whole buffer just after allocation?) So, IHMO Tomhet uses right tools here - there are a lot of commercial code working in similar way.
But, as MikeyBoy said:
And for dynamically allocating objects, you need to use new (and delete), to ensure your constructors (and destructors) are called properly.
when we're going to create instances of objects we must use new/delete, because we need constructor/destructor to be called. And in this context using malloc is formally incorrect.
I think the biggest problem here is that source and destination are not allowed to overlap in calls to strcpy (or strcat for that matter,) and they do when one tries to append a string to itself.