C++指针损坏
C++ pointer corruption?
老实说,我不知道标题对于我遇到的问题是否正确。 因此,问题在于。 我有一个名为 Engine 的类,其中有一个实例。
它包含两个成员变量(以及其他变量),分别称为 testTexture
,我的自定义Texture
类的实例,以及testObject
,我的自定义对象类的实例。
在引擎函数中Init
它们的值设置如下:
testTexture = Texture(0, TEXT("D:\spriteWallVertical112.png"),
renderer.ReturnDevice());
testObject = Object(0,testTexture.textureID, D3DXVECTOR3(0,0,0),
D3DXVECTOR3(100,100,100), testTexture.texture, &renderer);
这一切似乎都按照我想要的方式运行,它们的值被存储并且似乎维护得很好。
但是,在 Object
类构造函数中,我的 Renderer
类中有一个名为 AddNewTextureObject
的函数的调用:
rendererPointer->AddNewTextureObject(&objectID, &textureID, textureInput,
&origin, &coordinates);
这似乎很好,但是当程序运行值时,指针似乎随着程序的进行而被覆盖。 它们不会立即成为垃圾记忆,但很明显它们是。 我可以根据需要提供代码,但我不想只是用与问题无关的代码发送垃圾邮件,特别是如果其他人可能看到我做错了的明显事情。
但是,我现在将发布TextureObject
类代码,因为我认为它在这里最相关:
#ifndef TEXTUREOBJECT_H
#define TEXTUREOBJECT_H
#ifndef UNICODE
#define UNICODE
#endif
#include <d3dx9.h>
class TextureObject
{
public:
TextureObject();
TextureObject(unsigned int *, int *, LPDIRECT3DTEXTURE9, D3DXVECTOR3 *, D3DXVECTOR3 *);
~TextureObject();
unsigned int *objectID; // The object with the texture. Use this for locating and deleting this instance of TextureObject.
int *textureID;
LPDIRECT3DTEXTURE9 texture; // May not be needed if we can simply select the texture via ID.
const D3DXVECTOR3 *origin; // Needed for drawing rotations....I think.
D3DXVECTOR3 *coordinates;
int maintainMe;
};
#endif
如果我分配给变量maintainMe
,它确实会保留其值。
这是AddNewTextureObject()
函数的代码:
void Renderer::AddNewTextureObject(unsigned int *objectIDInput, int *textureIDInput, LPDIRECT3DTEXTURE9 textureInput, D3DXVECTOR3 *originInput, D3DXVECTOR3 *coordinatesInput)
{
//testTextureObject = TextureObject(objectID, textureID, textureInput, originInput, coordinatesInput);
testTextureObject.objectID = objectIDInput;
testTextureObject.textureID = textureIDInput;
testTextureObject.texture = textureInput;
testTextureObject.origin = originInput;
testTextureObject.coordinates = coordinatesInput;
testTextureObject.maintainMe = 3067;
请注意,将值分配给testTextureObject
的任何一种方法都会导致此问题。
任何这方面的帮助将不胜感激。
编辑:
下面是 Object
类的构造函数:
Object::Object(unsigned int objectIDInput, int textureIDInput, D3DXVECTOR3 originInput, D3DXVECTOR3 coordinatesInput, LPDIRECT3DTEXTURE9 textureInput, Renderer *rendererInput)
{
objectID = objectIDInput;
textureID = textureIDInput;
origin = originInput;
coordinates = coordinatesInput;
rendererPointer = rendererInput;
rendererPointer->AddNewTextureObject(&objectID, &textureID, textureInput, &origin, &coordinates);
}
它在Object
类中Object.h
声明为公共的,如下所示:
Object(unsigned int, int, D3DXVECTOR3, D3DXVECTOR3, LPDIRECT3DTEXTURE9, Renderer *);
编辑2:我做了一个复制构造函数和一个赋值运算符:
Object::Object(const Object &source)
{
objectID = source.objectID;
textureID = source.textureID;
texture = source.texture;
origin = source.origin;
coordinates = source.coordinates;
rendererPointer = source.rendererPointer;
}
Object& Object::operator=(const Object &source)
{
if(this == &source)
{
return *this;
}
objectID = source.objectID;
textureID = source.textureID;
texture = source.texture;
origin = source.origin;
coordinates = source.coordinates;
rendererPointer = source.rendererPointer;
return *this;
}
这些对你更有经验的人来说是正确的吗? 不幸的是,仅此一项似乎并不能解决问题。
由于您定义了析构函数,并且您的TextureObject
类中有指针,因此您需要遵循 3 规则:定义析构函数、复制构造函数和赋值运算符。似乎指针可能起源于Object
,所以你可能也需要为该类做同样的事情。
我想您面临的问题是悬空指针问题,因为在初始化testObject
后,用于初始化它的临时会破坏并释放在其中初始化的指针。因此,testTextureObject
现在持有指向释放内存的指针(因为这些指针最初来自临时内存)。
编辑:基于 Object
的构造函数,我们看到rendererPointer->AddNewTextureObject
正在从当前Object
实例传递指针,这将是临时实例。
testObject = Object(0,testTexture.textureID, D3DXVECTOR3(0,0,0),
D3DXVECTOR3(100,100,100), testTexture.texture, &renderer);
这行代码创建Object
的临时实例,然后使用赋值运算符初始化testObject
。在这行代码之后,临时将被销毁。现在,renderer
持有一个TextureObject
,该初始化为不再存在的临时指针。
编辑:您似乎对3法则试图帮助您解决的问题有些困惑。您可以阅读有关 3 法则问题的已接受答案。但是给你一个简单的例子,只要考虑一个分配内存的类的简单问题。
class Foo {
Bar *bar;
public:
Foo () : bar(new Bar) {}
~Foo () { delete bar; }
Bar * get_bar () { return bar; }
};
析构函数需要不泄漏内存。但是,如果使用复制构造函数或赋值运算符,则会引入问题。
Foo a;
Foo b(a); // copy
b
的问题在于它与a
持有相同的指针。因此,当b
和a
被破坏时,指针将被删除两次。
Foo a;
Foo c;
c = a; // assign
c
的问题在于,它不仅持有与a
相同的指针(这将导致双重删除),而且它在其构造函数中创建的任何内存现在都已泄露。
3 的规则是:如果需要析构函数,则复制构造函数和赋值运算符也需要。该规则的目的是让开发人员思考添加析构函数需要解决的问题,以及这些问题对复制构造和赋值的影响,并创建一个合理的解决方案。
在您的情况下,renderer
持有由临时Object
创建的TextureObject
。您需要考虑如何解决这种情况,无论是在析构函数、复制构造函数和 Object
赋值运算符中,还是通过避免使用其他解决方案解决问题。
- 堆损坏 c++ 返回表指针的函数
- C++指针:数组的堆栈已损坏
- 当使用实例会员方法作为函数指针时,堆积损坏
- 字符指针指向字符串,然后指向字符串数组。"./a.out"中的错误:malloc():内存损坏:0x0900c3b0***
- 指针函数参数已损坏,堆栈已损坏
- 损坏的指针-BST-调试
- 从函数返回时指针已损坏
- 通过 std::vector.data() 指向 std::vector 元素的指针指向损坏的数据
- C++指针损坏
- 删除数组指针C++时堆损坏
- 调用 C++ 成员函数指针:此指针已损坏
- 如果 EBP 帧指针为 NULL,堆栈是否损坏
- P/Invoke:指针内存损坏
- 从函数-堆损坏返回的void*指针
- 用错误的“”调用构造函数;这个“;指针.这是堆栈损坏吗
- 共享指针的双自由度或损坏
- 奇怪的指针损坏错误
- "this"指针在堆栈跟踪中损坏
- 删除指针会导致堆损坏
- 数组数据在传递指针C后损坏