Does calling ~myclass() (destructor) deletes the object?

Started by
29 comments, last by Zipster 8 years, 6 months ago

i fixed the code to

if (pdata != NULL)
{
delete[] pdata;
pdata = NULL;
}

but still calling tex->~TGLTexture();

throws errors i cant access the tex then

let me show you



void AppendLayers(AnsiString fname)
{


	layer_len = layer_len + 1;
	TGLTexture * tmp = new TGLTexture[layer_len];

	for (int i=0; i < layer_len-1; i++)
		{

		tmp[i].FileName = "1"; <- FileName is std::string <- i try to change that here is access violation whenever i use ~TGLTexture() in ResizeTexture() function but calling kill(), stores the object and there are no errors, i can access tmp[i]

		tmp[i].LoadTGA(layers[i].FileName);

		tmp[i].RelocateTo32Bit_from24();

		if( (tmp[i].px_width != 256) || (tmp[i].px_height != 256) )
		ResizeTexture(&tmp[i], 256);

		}

	delete [] layers;
	layers = NULL;

		layers = tmp;
		layers[layer_len-1].LoadTGA(fname);
		layers[layer_len-1].RelocateTo32Bit_from24();

		TGLTexture testtga; testtga.LoadTGA(fname);
		if( (testtga.px_width != 256) || (testtga.px_height != 256) )
			ResizeTexture(&layers[layer_len-1], 256);




		tmp = NULL;
		ReInit_LayerMenu();
}


if someone wants:

[spoiler]


	void ResizeTexture(TGLTexture * tex, int dim)
	{
		glClear(GL_DEPTH_BUFFER_BIT);
		glClear(GL_COLOR_BUFFER_BIT);
		glDisable(GL_DEPTH_TEST);
		glDepthMask(GL_FALSE);
		glActiveTexture(GL_TEXTURE0);
glViewport(0,0,dim,dim);
FULLSCREEN_SHADER->Enable();
FULLSCREEN_SHADER->Send1I(glGetUniformLocation(FULLSCREEN_SHADER->gProgram, "output_tex"), 0);
tex->Bind();
DrawFullScreenQuad(FULLSCREEN_SHADER);
FULLSCREEN_SHADER->Disable();
glViewport(0,0,SCREEN_WIDTH, SCREEN_HEIGHT);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
tex->kill(); //~TGLTexture(); gives error
unsigned char * kpdata = new unsigned char[dim*dim*4]; //conversion to rgba anyway
glReadPixels(0, 0, dim, dim, GL_RGBA, GL_UNSIGNED_BYTE, kpdata);
tex->pdata 		= kpdata;
tex->px_width 	= dim;
tex->px_height 	= dim;
tex->bpp = 4;
glGenTextures(1, &tex->texture);
	  glBindTexture(GL_TEXTURE_2D, tex->texture);

	  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dim, dim, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex->pdata);

tex->texloaded = true;
PUSH_EVENT("Texture resized to 256x256");
	} 

[/spoiler]

Advertisement

Why aren't you using a copy constructor in your loop?

you mean memcpy? it easier to recreate whole thing since maximum number of layers is 6, i don't have to add code for sharing opengl textures, and caring about accidentally deleting the texture object

... Wiredcat,


This is why you do proper RAII following rule-of-3 and using std::vector. If you do these things, you wouldn't need to worry about any of this nonsense.


Stop writing C and start using C++.

i already was using vector here, didin't fit my needs and opengl texture object wasnt stored TGLTexture mytex;

mytex.loadTGA(filename);

myvector.push_back(mytex); //didint store the unsigned int for opengl


i already was using vector here, didin't fit my needs and opengl texture object wasnt stored TGLTexture mytex;
mytex.loadTGA(filename);

myvector.push_back(mytex); //didint store the unsigned int for opengl

I don't know what this means. Why does it not fit your needs? I'm sure it actually does fit your needs, but you're dismissing it because you don't understand it. And then you end up having to write all this yucky code to manage something that should be handled for you.

If your TGLTexture class isn't copyable (I don't know if that's the case, but it seems like it might be, as TGLTexture may imply unique ownership of the underlying texture. So... is it copyable?), then you can just use a vector of unique_ptrs to TGLTexture instead.


std::vector<std::unique_ptr<TGLTexture>> layers;

then...



void AppendLayers(AnsiString fname)
{
	std::unique_ptr<TGLTexture> temp = std::make_unique<TGLTexture>();
	temp->LoadTGA(fname);
	temp->RelocateTo342Bit_from24();
	// resize, etc.. do all the things you need to do
	// Then add it to your vector:
	layers.push_back(std::move(temp)); // transfers ownership to your layers vector
}

That is why you should follow the rule of 3/5 and fix your texture class to at least have correct copy contructor, operator= and destructor.

class already contains copy constructor, so i reckon theres the problem, anyway i need special kind copy constructor here so it shares both opengl texture address and pixel data pointer.

ill post the code, just dont downvote ill show you, i need them to be shared not copied besides if i want to copy an opengl texture i would have to draw it on screen then read pixels and then create a texture


TGLTexture& operator=(const TGLTexture& in)
{
bpp 		= in.bpp;
height 		= in.height;
P0 			= in.P0;
P1 			= in.P1;
P2 			= in.P2;
P3 			= in.P3;
ID 			= in.ID;


pdata 		= in.pdata; //shared data
px_width 	= in.px_width;
texloaded 	= in.texloaded;
texture 	= in.texture; //opengl shared data
use_alpha 	= in.use_alpha;
width 		= in.width;
return *this;
}


pdata = in.pdata; //shared data
texture = in.texture; //opengl shared data


This is bad, because now two TGLTexture objects technically own "pdata" and "texture". Which TGLTexture object is supposed to free/release them?

you mean memcpy? it easier to recreate whole thing since maximum number of layers is 6, i don't have to add code for sharing opengl textures, and caring about accidentally deleting the texture object

Nope I meant this:


void AppendLayers(AnsiString fname)
{


	layer_len = layer_len + 1;
	TGLTexture * tmp = new TGLTexture[layer_len];

	for (int i=0; i < layer_len-1; i++)
	{

		//Update layer_len data if you actually need to
                tmp[i] = TGLTexture(layers[i]); //<- copy constructor (note the lack of new)
	}

	delete [] layers;
	layers = NULL;

		layers = tmp;
		layers[layer_len-1].LoadTGA(fname);
		layers[layer_len-1].RelocateTo32Bit_from24();

		TGLTexture testtga; testtga.LoadTGA(fname);
                layers[layer_len-1].Resize(256,256); //this if width != 256 and height != 256 logic should be in the method for resizing

		//if( (testtga.px_width != 256) || (testtga.px_height != 256) )
		//	ResizeTexture(&layers[layer_len-1], 256);

		ReInit_LayerMenu();
}


This topic is closed to new replies.

Advertisement