Reputation: 665
i wrote a class named octed_string , without a destructor it works well but with that it could not return any octed_string type in function.
please look at the code below and tell me what is wrong .
when i delete the destructor it work! (cout print 12)
can any one help?
class octed_string
{
private:
uint8_t *value;
size_t length;
size_t allocated;
public:
octed_string()//constructor
:value(0),length(0),allocated(0)
{
}
void copy(uint8_t *from, uint8_t *to)
{
for (size_t i = 0; i < length; i++)
*to++ = *from++;
}
void allocate()
{
if (value == 0)
{
allocated = STACK_INITIAL_ALLOC;
value = new uint8_t[allocated];
}
else
{
// We need to allocate more memory
size_t new_allocated = allocated + STACK_CHUNK_ALLOC;
uint8_t *new_value = new uint8_t[new_allocated];
// Copy from old stack to new stack
copy(value, new_value);
// Delete the old value
delete [] value;
allocated = new_allocated;
value = new_value;
}
}
~octed_string()//destructor
{
if(value)
delete [] value;
}
friend ostream &operator<<(ostream &_output,const octed_string &_str)//opration overloading for cout
{
for(int i=0;i<_str.length;i++)
_output<<(uchar_t)_str.value[i];
return _output;
}
void add(uint8_t input)//this function automatically add space to value (new)
{
if (length == allocated)
allocate(); // Allocate more memory
value[length++] = _value;
}
octed_string sub_string(int start,int end)//( this function has a problem with destructor i think because it return octed_string)
{
octed_string a;
for(int i=start;i<end;i++)
a.add(a);
return a;
}
};
void main()
{
octed_string o; //object
o.add(1);
o.add(2);
o.add(3);
cout<<o.sub_string(0,2); //i expect printing 12 but i does not!
}
-----------------------//answer thanks to phresnel it fix by adding following codes:
octed_string(const octed_string &_input)
:value(0),length(0),allocated(0)
{
while(length<_input.length)
{
this->add((uchar_t)_input[length]);
}
}
octed_string& octed_string::operator= (octed_string const& _in)
{
octed_string tmp(_in);
return *this;
}
but i still can not understand the reason. could any body show any reference to learn this issue?
Upvotes: 2
Views: 220
Reputation: 1
Any class that has member variable of type pointer, needs a copy constructor, overloaded operator =, and destructor.
Consider the following code:
octed_string str1; // suppose this is initialized as desired
octed_string str2 = str1;
At the second line, the compiler generated copy constructor is called, which copies the members one by one. Here we have a char_t* member named value. So, the value of str2 points to the same memory location of str1. This is called shallow copy. In this case, both str1 and str2 share the same memory location for value, which will cause dangling pointers if str1 goes out of scope. The following code shows one possible situation of this fact:
octed_string test() {
octed_string str;
// Initialize str...
return str;
}
The same story applies to assignment of objects.
Upvotes: 0
Reputation: 7677
What are you trying to achieve? Is it anything that cannot be achieved using std::string?
Couple of comments:
1 How are you newing value inside add?
2 prefix underscores (_output) area a bad idea
3 You need to define a copy constructor e.g:
// Assuming value is an array
octed_string::octed_string( const octed_string& rhs)
: value( rhs.value ? new uint8_t[ rhs.length ] : 0 )
, length( rhs.length )
, allocated( rhs.allocated )
{
}
4 You also need an assignment operator
octed_string& octed_string::operator= (octed_string const& f)
{
octed_string tmp( f );
std::swap( tmp, *this );
return *this;
}
Upvotes: 1
Reputation: 39109
Possible reasons:
sub_string
, but not sub_stirng
.add()
function is empty
delete
the value buffervalue
buffer.
value
-buffer at allA better answer is not really possible without actual code.
Upvotes: 1
Reputation: 122011
You need to define a copy constructor, and assignment operator, for octed_string
.
When you do not have a destructor it works because the memory allocated for member variable value
is not destroyed and the copy constructed by the default copy constructor refers to the same undeleted memory that original, now destroyed, object did.
When you do have a destructor the memory is deleted.
The copy is created when sub_string()
returns.
Upvotes: 11