Colin Moore Colin Moore - 16 days ago 5
C++ Question

c++ Segmentation Fault passing in pointer to function

I'm writing code to fill a texture class with data from an image file. As far as I can tell, the code and implementation works, however it causes a segmentation fault on entering the main loop of my program. These 4 lines, when removed, remove the segmentation fault:

Texture* texture = new Texture(); // Dynamically allocate texture object to texture pointer
bool success = loadTexture(texture, "C:/pathToImage/image.png"); // Function that gets image data
cout << success << endl; // Print out success or not
textures.push_back(*texture); // put texture in a vector of textures


Edit: texture.h

class Texture {
public:
Texture();
Texture(const Texture&);
~Texture();
Texture& operator=(const Texture&);
public:
void init();
int width, height;
std::vector<unsigned char> pixmap;
GLuint id;
};


texture.cpp:(The init function is edited out, as it doesn't pertain to the error, it isn't even called.)

Texture::Texture() : width(0), height(0), pixmap(), id(int(-1)){}
Texture::Texture(const Texture& other) : width(other.width), height(other.height), pixmap(other.pixmap), id(other.id){}
Texture::~Texture()
{
width = 0;
height = 0;
delete &pixmap;
id = int(-1);
}
Texture& Texture::operator=(const Texture& other) {
width = other.width;
height = other.height;
pixmap = other.pixmap;
id = other.id;
}


I'm assuming it has something to do with the texture pointer, however I've tried several methods of doing this same thing, and they've all caused the same segmentation fault. Could someone explain what's causing this?

Answer

Your error is because the Texture class is not following the rule of three. 'Any class which has one of a destructor, copy constructor or assignment operator most likely needs all three'.

What is The Rule of Three?

Specifcally what is probably happening is that because you have not defined a copy constructor your object is being shallow copied into the vector. This results in two Texture objects sharing the same pixmap data. When one of those objects is destructed, this invalidates the pixmap data in the other object.

For instance one possibility for the copy constructor is this

Texture::Texture(const Texture& other) : width(other.width), height(other.height), pixmap(NULL), id(other.id)
{
    pixmap = new unsigned char[width*height];
    memcpy(pixmap, other.pixmap, width*height);
}

Only one way to do it. cHao is suggesting other possibilities.

Comments