Reputation: 1292
I currently have a class called TextureObject. In the creation function I create the texture, and assign a LPCSTR in the class to a parameter given in the function. When I return that LPCSTR later, it returns in an unexpected manner.
Some type names and functions are from DirectX 11, just ignore them.
Code:
The h File:
class TextureObject
{
public:
ID3D11ShaderResourceView *pTexture;
LPCSTR GetFilename() const { return *FFilename; }
bool IsNotNull;
void CreateTexture(ID3D11Device &dev,LPCSTR Filename);
void ReCreate(ID3D11Device &dev);
void Release();
int relativeId;
private:
LPCSTR *FFilename;
};
The cpp file:
void TextureObject::CreateTexture(ID3D11Device &dev,LPCSTR Filename)
{
D3DX11CreateShaderResourceViewFromFile(
&dev, // the Direct3D device
Filename, // load Wood.png in the local folder
NULL, // no additional information
NULL, // no multithreading
&pTexture, // address of the shader-resource-view
NULL); // no multithreading
FFilename = new LPCSTR(Filename);
IsNotNull = true;
}
void TextureObject::ReCreate(ID3D11Device &dev)
{
CreateTexture(dev, *FFilename);
}
When using vs 2012 debugger in the CreateTexture function, the Filename debugger values are:
0x0a06fed0 "C:\Users\Utilizador\Desktop\particle.png"
Which is perfect for me! When i assign the class's FFilename:
FFilename = new LPCSTR(Filename);
It's ok. When I check the value of FFilename within the scope of this function, it's the same value of the Filename. But when i use GetFilename, things start getting crazy:
= 0x0a06fed0 "îþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþü =I.C"
Mmm, I just met you, and this is crazy, but... Here's my value. mKay?
Well, please help me. Thank You
Upvotes: 1
Views: 1383
Reputation: 6678
As marcin_j said, use std::[w]string. As for the line:
FFilename = new LPCSTR(Filename);
It just allocates 4 bytes for a pointer and initializes it to the filename string. It doesn't actually copy the string. So you can still use the string, but it is owned by whoever calls TextureObject::CreateTexture, and may be released while TextureObject is still referencing it.
Change the class to:
class TextureObject
{
public:
// ...all the same stuff as before...
private:
wstring FFilename; // it's better to store filenames as Unicode
};
And the methods to:
void TextureObject::CreateTexture(ID3D11Device* dev, const wstring& Filename)
{
D3DX11CreateShaderResourceViewFromFile(
dev, // the Direct3D device
Filename.c_str(), // load Wood.png in the local folder
NULL, // no additional information
NULL, // no multithreading
&pTexture, // address of the shader-resource-view
NULL); // no multithreading
FFilename = Filename;
IsNotNull = true;
}
void TextureObject::ReCreate(ID3D11Device* dev)
{
CreateTexture(dev, FFilename.c_str());
}
Upvotes: 1
Reputation: 63481
You are not copying the string. You are copying the pointer. I think you probably wanted to copy the string, because you cannot guarantee the caller's pointer will still reference valid data at a later time.
LPCSTR
is just a const char*
. There's probably a corresponding windows call, but I would just use strdup
to copy the string.
Define FFilename
as LPCSTR
:
LPCSTR FFilename;
And then:
void TextureObject::CreateTexture(ID3D11Device &dev,LPCSTR Filename)
{
D3DX11CreateShaderResourceViewFromFile(
&dev, // the Direct3D device
Filename, // load Wood.png in the local folder
NULL, // no additional information
NULL, // no multithreading
&pTexture, // address of the shader-resource-view
NULL); // no multithreading
FFilename = strdup(Filename);
IsNotNull = true;
}
void TextureObject::ReCreate(ID3D11Device &dev)
{
CreateTexture(dev, FFilename);
}
Since you are using C++, you are free to use std::string
instead, which will be cleaned up automatically when the object is destroyed.
Upvotes: 2
Reputation: 308392
When you create your pointer FFilename
, you're initializing it with another pointer. That's not going to make a copy of the string, now you have two pointers pointing to the same thing. Presumably that thing is a temporary object, and when you go to look at it later it's no longer valid.
I'd suggest using std::string
for this instead, it's much less error prone. The c_str
method can get a LPCSTR
at any time.
Upvotes: 2