指针问题(仅在发布版本中)

时间:2011-11-08 00:26:26

标签: c++ visual-c++-2010

不确定如何描述这个但是我在这里:

出于某种原因,在尝试创建我的游戏的发布版本以进行测试时,它的敌人创建方面无法正常工作。

Enemies *e_level1[3];
e_level1[0] = &Enemies(sdlLib, 500, 2, 3, 128, -250, 32, 32, 0, 1);
e_level1[1] = &Enemies(sdlLib, 500, 2, 3, 128, -325, 32, 32, 3, 1);
e_level1[2] = &Enemies(sdlLib, 500, 2, 3, 128, -550, 32, 32, 1, 1);

这就是我如何创造我的敌人。在调试配置中工作正常,但是当我切换到发布配置时,它似乎没有正确初始化敌人。

对我来说,这看起来有点奇怪,它在调试中有效,但在发布时却没有,任何帮助都会对我做错了什么有所帮助。

5 个答案:

答案 0 :(得分:5)

e_level1[0] = &Enemies(sdlLib, 500, 2, 3, 128, -250, 32, 32, 0, 1);

不符合您的想法。如果是构造函数调用,则会创建一个临时函数,并将其地址存储在e_level1 [0]中。当初始化e_level1 [1]时,可能已经调用了e_level1 [0]析构函数。

您可能想要

Enemies* e_level1[3] = 
    {
        new Enemies(sdlLib, 500, 2, 3, 128, -250, 32, 32, 0, 1) , 
        new Enemies(sdlLib, 500, 2, 3, 128, -325, 32, 32, 3, 1) , 
        new Enemies(sdlLib, 500, 2, 3, 128, -550, 32, 32, 1, 1)
    };

答案 1 :(得分:3)

其他人已经指出了这个错误,即临时状态正在被摧毁,但到目前为止所有的答案都是使用手动内存管理 - 在C ++中使用例如更加惯用。 std::vector这样的事情,例如。

std::vector<Enemies> enemies;
enemies.push_back(Enemies(sdlLib, 500, 2, 3, 128, -250, 32, 32, 0, 1));
enemies.push_back(Enemies(sdlLib, 500, 2, 3, 128, -325, 32, 32, 3, 1));
enemies.push_back(Enemies(sdlLib, 500, 2, 3, 128, -550, 32, 32, 1, 1));

然后,您只需通过Enemies访问enemies[0]enemies[2]个实例,当向量超出范围时,它们会自动清理。

答案 2 :(得分:2)

大多数调试模式会将所有内存初始化为零。在正常执行中,它可能是随机的。

让你的编译器尽可能繁琐(你应该已经这样做了)并修复所有警告。

如果它仍然存在,你应该在像valgrind这样的内存检查工具中运行它。

答案 3 :(得分:2)

代码初始化指针以指向立即销毁的临时对象。通过指针或引用访问不再存在的临时对象是未定义的行为。你想要:

Enemies *e_level1[3];
e_level1[0] = new Enemies(sdlLib, 500, 2, 3, 128, -250, 32, 32, 0, 1);
e_level1[1] = new Enemies(sdlLib, 500, 2, 3, 128, -325, 32, 32, 3, 1);
e_level1[2] = new Enemies(sdlLib, 500, 2, 3, 128, -550, 32, 32, 1, 1);

答案 4 :(得分:-1)

您似乎在堆栈上创建了Enemies对象,这意味着当它们超出范围时,您的e_level1指针指向已被销毁的对象。 (证据:在Enenmies类析构函数中放置一个断点,并在遇到它时看到它)因此,当你试图取消引用它们时,你会得到垃圾。

你想要的是:

for( size_t i = 0; i < 3; i++ )
    e_level1[i] = new Enemies( sdlLib, ... );

这将在堆上创建对象。这也意味着您将需要使用以下命令销毁对象:

for( size_t i = 0; i < 3; i++ )
    delete ( e_level + i );