使用关键字"new"创建的C++对象不会显示;而在栈上创建的对象会显示。

6
编辑:我已经去除了所有纹理和法线映射,但问题仍然存在。
我正在尝试在屏幕上绘制一块地形。渲染函数如下:
void TerrainChunk::Render()
{
   std::cout << "Render Me!\n";
   glColor3f(0.5f, 0.5f, 0.5f)
   glDisable(GL_LIGHTING);
   for(int x = 1; x < kChunkSize - 1; x++)
   {
      for(int z = 1; z < kChunkSize - 1; z++)
      {
         std::cout << height_map_[x][z] << " ";
         glBegin(GL_TRIANGLE_STRIP);
            glVertex3f(x, height_map_[x][z], z);
            glVertex3f(x+1, height_map_[x+1][z], z);       
            glVertex3f(x, height_map_[x][z+1], z+1);
            glVertex3f(x+1, height_map_[x+1][z+1], z+1);
         glEnd();
      }
      std::cout << std::endl;
   }
   glEnable(GL_LIGHTING);
}

当对象在栈上创建时

TerrainChunk chunk("chunk1.png", "grass.png");
chunk.Init();

它的呈现完美无缺。

当我使用new创建它时

TerrainChunk *chunk = new TerrainChunk("chunk1.png", "grass.png");
chunk->Init();

什么也没有显示出来。在这两种情况下,Render都被调用了,并且正确的高度图被打印出来了。我希望这两种情况的行为是相同的。

编辑:根据要求,这里是Init()代码。它所做的只是加载高度图,我已经验证了每次Render()调用时高度图都是正确的。

void TerrainChunk::Init()
{
   std::cout << height_file_ << ", " << texture_file_ << std::endl;

   //Load height map
   SDL_Surface *temp = IMG_Load(height_file_.c_str());
   if(!temp)
   {
      printf("Failed to load chunk.\n");
      exit(-1);
   }
   Uint32 *pixels = (Uint32 *)temp->pixels;
   for(int z = 0; z < kChunkSize; z++)
   {
      for(int x = 0; x < kChunkSize; x++)
      {
         Uint8 r, g, b;
         SDL_GetRGB(pixels[x + z * temp->w], temp->format, &r, &g, &b);
         height_map_[x][z] = g / 12;
      }
   }
}

1
两种情况下的代码除了切换构造语法和适当的点(.)和箭头(->)之外完全相同。它在两种情况下都打印出“Render Me!”和正确的高度图。 - Timulus
5
我曾经见过在operator new操作符中进行零初始化的错误,但如果实例位于堆栈上,则不会运行。此外,分配的内存比堆栈内存更有可能具有一致的值。未初始化的堆栈空间中的值通常会更加混乱,或许通过偶然情况下分配在堆上的实例具有更好的未初始化值。我建议在构造函数末尾设置断点,并检查所有成员变量的值。 - doug65536
3
另外,你是否有像 Mac 上的 OpenGL Profiler 一样的调试工具?它可以对 OpenGL 状态进行快照并将其保存为文本文件。然后,您可以比较两个文本文件,一个是正常工作时的状态,另一个是出现问题时的状态,以确定它们之间的区别。 - user1118321
@Timulus,我们能看到TerrainChunk的构造函数吗? - QAH
2
这真是令人难以置信。如果可能的话,我很想看到完整的代码。你确定没有其他地方被更改了吗?height_map_声明在哪里?如果cout的输出相同,那么肯定会调用glVertex3f()并产生相同的输出。结论:1)你的代码中有其他地方出现了错误,或者2)你没有只更改初始化(无论是出于错误还是副作用)。 - the swine
显示剩余16条评论
2个回答

1

当相同的对象在栈上创建时可以工作,但在堆中创建时却不能工作,或者反之亦然,往往是因为一个成员未被初始化。堆分配会进行零初始化,而栈分配则不会。我建议您在valgrind下运行程序,它很可能会告诉您问题所在。


0

我得同意Luchian Grigore的观点:基于栈的版本将在使用完成后自动删除;而基于堆的版本则需要显式地进行删除。

如果你进行了以下更改:

TerrainChunk *chunk = new TerrainChunk("chunk1.png", "grass.png");
chunk->Init();

致:

TerrainChunk *chunk = new TerrainChunk("chunk1.png", "grass.png");
chunk->Init();
delete chunk;

结果不同吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接