我一直在关注youtube上使用SDL的游戏引擎创建者教程。我已经学习了C ++涉及的许多东西,并且深入研究了指针(原始和智能),并了解了堆栈和堆。在教程中,有一个小函数可以返回一个指针。我不明白的是在整个代码执行过程中该指针如何仍然可用?这是有问题的代码。
SDL_Texture* TextureManager::LoadTexture(const char* texture)
{
SDL_Surface* tempSurface = IMG_Load(texture);
SDL_Texture* tex = SDL_CreateTextureFromSurface(Game::renderer,
tempSurface);
SDL_FreeSurface(tempSurface);
return tex;
}
这段代码包含整个指针信息...
现在,为了学习这种材料,我尝试创建类似的东西来观察内存如何与我创建的函数中的指针一起工作。
int* test() {
int num = 5;
return #
}
int main()
{
int* ptr = nullptr;
ptr = test();
std::cout << "Hello World!\n";
int testArray[5];
int i = 1;
testArray[0] = 1;
testArray[1] = 2;
}
调用int i时,指针信息被破坏。为什么缺少与上面的功能相同的功能,我还缺少什么?
答案 0 :(得分:1)
在test
函数中,num
是局部变量。它在test()
的末尾被销毁。
您需要在test
中分配一个整数以使其起作用。在这种情况下,指针的所有权会转让给您:您需要删除它。
int* test() {
int* num = new int(5);
return num;
}
int main() {
int* ptr = test();
std::unique_ptr<int> int_deleter(ptr);
std::cout << "Hello World!\n" << *ptr;
}
另一个返回指针的例子是返回一个类成员。在这种情况下,请参阅有关是否转移所有权的文档。例如:
class A {
public:
A() : num(new int(5)) {}
virtual ~A () { delete num; }
// `A` keeps the ownership of the pointer.
const int* GetNum() const { return num; }
private:
int* num;
}
int main() {
A a;
std::cout << *a.GetNum() << std::endl;
}
回到SDL_CreateTextureFromSurface
示例,很可能在该方法中分配了一个新变量。您需要参考documentation关于返回的指针的所有权(无论您是删除库还是删除库)。
答案 1 :(得分:1)
因此,test()
中断了this rule right here。
不幸的是,我为什么找不到足够的研究来满足我为什么要这样做,但是我会提出怀疑。
num
是局部变量。局部变量在堆栈上分配。函数完成执行的那一刻,局部变量(即num
)被“弹出”堆栈。也就是说,它们被摧毁了。
通过malloc()
或new
关键字之类分配的变量在堆上分配。 程序
在这种情况下,存储在num中的地址:
int *num = new int(37);
是堆上的地址。即使功能完成执行后,它也完全有效。因此,您可以在功能完成后使用它。
答案 2 :(得分:1)
除了其他答案外,SDL是C(不是C ++)API,因此它没有RAII,这意味着不存在自动调用构造函数和析构函数的环境。
您需要调用SDL_DestroyTexture
释放纹理。否则,将导致内存泄漏,这与局部变量不同。
您可能会在概念上想到
SDL_CreateTextureFromSurface()
(或其他纹理生成API)为new SDL_Texture
SDL_DestroyTexture(texture)
为delete texture
答案 3 :(得分:0)
C / C ++中有4种基本存储类:
因此通常,将引用/指针返回到任何非自动对象都是可以的。