Page 1 of 1

OH NOOOOOOOOOOOOOO

Posted: Mon Jul 23, 2012 10:34 am
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?

Re: OH NOOOOOOOOOOOOOO

Posted: Mon Jul 23, 2012 11:03 am
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.

Re: OH NOOOOOOOOOOOOOO

Posted: Mon Jul 23, 2012 11:54 am
by Rebornxeno
I tried initializing more ID3DDeviceContext but that didnt help my problem at all

Re: OH NOOOOOOOOOOOOOO

Posted: Mon Jul 23, 2012 3:17 pm
by short
Rebornxeno wrote:I tried initializing more ID3DDeviceContext but that didnt help my problem at all
I don't understand

Re: OH NOOOOOOOOOOOOOO

Posted: Mon Jul 23, 2012 4:17 pm
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) {}

Re: OH NOOOOOOOOOOOOOO

Posted: Mon Jul 23, 2012 5:07 pm
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

Re: OH NOOOOOOOOOOOOOO

Posted: Mon Jul 23, 2012 5:44 pm
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

Re: OH NOOOOOOOOOOOOOO

Posted: Tue Jul 24, 2012 6:14 am
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.

Re: OH NOOOOOOOOOOOOOO

Posted: Tue Jul 24, 2012 10:13 am
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