468,747 Members | 1,790 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,747 developers. It's quick & easy.

Copy Constructor segmentation fault

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);
}

Apr 5 '06 #1
2 4535

pr********@gmail.com wrote:
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

Apr 5 '06 #2
pr********@gmail.com wrote:
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

Apr 5 '06 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

42 posts views Thread by Edward Diener | last post: by
5 posts views Thread by Fra-it | last post: by
18 posts views Thread by Digital Puer | last post: by
27 posts views Thread by Paminu | last post: by
1 post views Thread by samuel.y.l.cheung | last post: by
5 posts views Thread by sarathy | last post: by
7 posts views Thread by pycraze | last post: by
3 posts views Thread by madunix | last post: by
reply views Thread by zhoujie | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.