OH NOOOOOOOOOOOOOO

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

Post Reply
Rebornxeno
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 85
Joined: Thu Jun 23, 2011 11:12 am

OH NOOOOOOOOOOOOOO

Post by Rebornxeno »

Hey guys, I got a problem! I know a solution, but I'm really hoping and believe there is a way around this.

Code: Select all

struct IndexBuffer
{
	ID3D11Buffer* index;
	UINT size;
	IndexBuffer(){}
	~IndexBuffer()
	{
		if(index) index->Release();
	}

	IndexBuffer(ID3D11Buffer* i, UINT s)
	{
		index = i;
		size = s;
	}
	IndexBuffer(UINT s)
	{
		size = s;
	}
	ID3D11Buffer** operator()()
	{
		return &index;
	}
	IndexBuffer(const IndexBuffer& ib) : index(ib.index), size(ib.size){}
	IndexBuffer& operator=(const IndexBuffer& ib)
	{
		index = ib.index;
		size = ib.size;
		return *this;
	}
};
I initialize this in another constructor somewhere like this

Code: Select all

index = IndexBuffer(500);
This causes an error as the destructor is being called on the IndexBuffer(500) object after its done copying its stuff to index. How can I stop this? I'm sure it'll stop if instead of initializing with a constructor I use a member function like INIT, but there are many structs like this and I'd hate to change them all! So anyone know how I can stop this?
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: OH NOOOOOOOOOOOOOO

Post by short »

Use initialization instead of assignment.

ie:

Code: Select all

IndexBuffer index(500);
This will invoke the copy constructor, which you should also define if you have not (since you defined the assignment operator)

Code: Select all

IndexBuffer::IndexBuffer(const IndexBuffer &other) : index(other.index), size(other.size) { }
[/s]

Nevermind you already defined one, maybe I should wait until I finish the morning cup of coffee.

To solve your problem though, a little more context would help.
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
Rebornxeno
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 85
Joined: Thu Jun 23, 2011 11:12 am

Re: OH NOOOOOOOOOOOOOO

Post by Rebornxeno »

I tried initializing more ID3DDeviceContext but that didnt help my problem at all
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: OH NOOOOOOOOOOOOOO

Post by short »

Rebornxeno wrote:I tried initializing more ID3DDeviceContext but that didnt help my problem at all
I don't understand
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
User avatar
Nokurn
Chaos Rift Regular
Chaos Rift Regular
Posts: 164
Joined: Mon Jan 31, 2011 12:08 pm
Favorite Gaming Platforms: PC, SNES, Dreamcast, PS2, N64
Programming Language of Choice: Proper C++
Location: Southern California
Contact:

Re: OH NOOOOOOOOOOOOOO

Post by Nokurn »

I see that you're checking if index is non-NULL in the destructor before releasing it. This is fine, except the constructor you're using (UINT s) does not initialize index, only size. index is going to have a garbage value. The release will proceed on an address that doesn't contain an ID3D11Buffer; you might not even have access to this address. This can be solved as such:

Code: Select all

IndexBuffer(UINT s) : index(0), size(s) {}
Rebornxeno
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 85
Joined: Thu Jun 23, 2011 11:12 am

Re: OH NOOOOOOOOOOOOOO

Post by Rebornxeno »

Hahaahahahaha!!! I did that exact same thing on the empty constructor, thinking it would work the exact same, but it didn't, as doing that solved the issue. So why doesn't it work with the empty constructor? Here's a piece of implementation to show what I'm asking.

Code: Select all

struct IndexBuffer
{
    ID3D11IndexBuffer * ib;
    UINT size;
    IndexBuffer():ib(0){}
    IndexBuffer(UINT s,IndexBuffer i)
    {
        size = s;
        ib = i;
    }
    IndexBuffer(UINT s)
    {
        size = s;
    }
}
class someclass
{
    IndexBuffer ib;//does this not call the empty constructor? it requires that I have one if I do this
public:
    someclass()
    {
        ib = IndexBuffer(500);
    }
}
ohh I think I figured it out. When I first declare the ib object, it DOES work as intended, and sets the pointer to 0, however, when I use the assignment operator, the IndexBuffer(500) object DOESN'T have the pointer set to 0, and then when it copies the variables over, it copies over the 0 and puts an undefined variable in its place.

Oh and short, you said if I had more context it might help to solve my problem, so I joked about adding more Context objects to the program
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: OH NOOOOOOOOOOOOOO

Post by short »

Code: Select all

Oh and short, you said if I had more context it might help to solve my problem, so I joked about adding more Context objects to the program
haha
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
User avatar
bbguimaraes
Chaos Rift Junior
Chaos Rift Junior
Posts: 294
Joined: Wed Apr 11, 2012 4:34 pm
Programming Language of Choice: c++
Location: Brazil
Contact:

Re: OH NOOOOOOOOOOOOOO

Post by bbguimaraes »

Rebornxeno wrote:So why doesn't it work with the empty constructor?
The empty constructor (aside from being useless, since the compiler will add one for you) doesn't initialize the pointer. It will have a garbage (i.e. random) value, as Nokurn said. That is not the problem, it's the cause. The problem is that your destructor deletes the memory assigned to that pointer. So, if you don't assign anything to that pointer, when the destructor is called, it will try to delete a random place in memory, which causes the program to crash (if you're lucky). Note that the test

Code: Select all

if(index)
only returns false if the pointer is null, not if it's invalid.

Another issue you will face is that, when copying an index buffer, the pointer is copyied, so both objects now share the same index. If both get destructed, both will delete the same are in memory, causing the second delete to crash.
Rebornxeno
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 85
Joined: Thu Jun 23, 2011 11:12 am

Re: OH NOOOOOOOOOOOOOO

Post by Rebornxeno »

The empty constructor in the first post i made doesn't set the pointer, but in the other post where the constuctor is

Code: Select all

SomeClassConstrctor():somepointer(0){}
it does set it to 0 as intended
Post Reply