Copy Constructor segmentation fault

P

pragtideep

Kindly help me explain the behaviour of defult copy constructor . Why
the destructor is freeing the SAME memory twice , though it was
allocated just once .

#include<iostream>
using namespace std;
class var_array
{
private:
int *data; // The data
const int size; // The size of the data
public:
var_array(const int _size):
size(_size)
{
data = new int[size];
memset(data, '\0',
size * sizeof(int));
}
// Destroy the var_array
~var_array(void) {
delete []data;
}
public:
// Get an item in the array
int &operator [] (
// Index into the array
const unsigned index
)
{
return (data[index]);
}
};
static void store_it(
var_array test_array
)
{
test_array[7] = 7;
}


int main()
{
var_array test_array(30);
store_it(test_array);
return (0);
}
 
S

Sunil Varma

Kindly help me explain the behaviour of defult copy constructor . Why
the destructor is freeing the SAME memory twice , though it was
allocated just once .

#include<iostream>
using namespace std;
class var_array
{
private:
int *data; // The data
const int size; // The size of the data
public:
var_array(const int _size):
size(_size)
{
data = new int[size];
memset(data, '\0',
size * sizeof(int));
}
// Destroy the var_array
~var_array(void) {
delete []data;
}
public:
// Get an item in the array
int &operator [] (
// Index into the array
const unsigned index
)
{
return (data[index]);
}
};
static void store_it(
var_array test_array
)
{
test_array[7] = 7;
}


int main()
{
var_array test_array(30);
store_it(test_array);
return (0);
}

In store_it() method the argument is of type var_array.
So once you pass object of var_array as an argument, copy constructor
is called.
If not provided compiler provides the default copy constructor, which
copies the data bit by bit.
Now the the pointer is copied to the local object which points to
memory allocated by the calling argument.
As the object goes out of scope the destructor is called, which delete
[]s the data.
Now the control returns to main().
Now in main() the test_array object holds the data variable which
points to a location that has been deleted(a dangling reference).
When main exits the destructor is called for the test_array object.
Trying to delete a pointer that has already been deleted causes a
segmentation fault.

Regards
Sunil Varma
 
M

mlimber

Kindly help me explain the behaviour of defult copy constructor . Why
the destructor is freeing the SAME memory twice , though it was
allocated just once .

#include<iostream>

Nitpick: You don't use this header.
using namespace std;
class var_array
{
private:
int *data; // The data
const int size; // The size of the data
public:
var_array(const int _size):
size(_size)
{
data = new int[size];
memset(data, '\0',
size * sizeof(int));
}
// Destroy the var_array
~var_array(void) {
delete []data;
}
public:
// Get an item in the array
int &operator [] (
// Index into the array
const unsigned index
)
{
return (data[index]);
}
};

It's fine if you're doing this as an exercise, but in general, prefer
to use std::vector, which provides the same functionality in a working,
standard form.
static void store_it(

Using static to indicate "local to this translation unit" has been
deprecated in C++. Use anonymous namespaces instead.
var_array test_array

The basic problem is this: you are copying the object, and the default
copy constructor just copies its members "dumbly." It doesn't allocate
new memory and copy the existing array values into the new memory; it
just copies the address of the existing array into the new object that
is created here. Then, when the function completes, it executes the
destructor, deleting the memory that is pointed to in both by your
var_array classes, and Bang! you have a dangling pointer.

You should pass this parameter by reference rather than by value to
prevent the invocation of the copy constructor. If you don't need to
modify it, pass it by const reference (you'll also need to add a const
version of operator[]). Alternately, you could write a copy constructor
(and assignment operator!) that gives whatever non-default behavior you
want. Moreover, you could use a smart pointer or smart array such as
those supplied by Boost to manage the memory. The best option, though,
is to use std::vector.
)
{
test_array[7] = 7;
}


int main()
{
var_array test_array(30);
store_it(test_array);
return (0);
}

Cheers! --M
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top