在一个循环中对 2 个向量进行操作时出现问题
Issue with operations on 2 vectors in one loop
当我使用此循环时,代码无法正常工作:
for(int i = 0; i < INTRO_LOGO_COUNT; i++)
{
char path_buffer[32]; // 32 = logo_xxx.png
sprintf(path_buffer, "data/texture/intro/logo_%d.png", i);
std::cout << path_buffer;
m_vecTextures.push_back(sf::Texture());
m_vecTextures.back().loadFromFile(path_buffer);
m_vecSprites.push_back(sf::Sprite());
m_vecSprites.back().setTexture(m_vecTextures[i]);
// Center
m_vecSprites.back().setPosition(
SCREEN_WIDTH / 2 - m_vecSprites.back().getLocalBounds().width / 2,
SCREEN_HEIGHT / 2 - m_vecSprites.back().getLocalBounds().height / 2);
m_vecSprites.back().setColor(sf::Color(255, 255, 255, 0)); // Opacity : 100%
}
纹理变得混合,只有第二个纹理正常工作。(INTRO_LOGO_COUNT定义为 2)第一个纹理具有有效大小,但图像来自第二个纹理。第二个纹理具有有效的大小和图像。但是在 1 次更改(溢出到 2 个循环)之后:
for( int i = 0; i < INTRO_LOGO_COUNT; i++ )
{
char path_buffer[32]; // 32 = logo_xxx.png
sprintf(path_buffer, "data/texture/intro/logo_%d.png", i);
std::cout << path_buffer;
m_vecTextures.push_back(sf::Texture());
m_vecTextures.back().loadFromFile(path_buffer);
}
for( int i = 0; i < INTRO_LOGO_COUNT; i++ )
{
m_vecSprites.push_back(sf::Sprite());
m_vecSprites.back().setTexture(m_vecTextures[i]);
// Center
m_vecSprites.back().setPosition(
SCREEN_WIDTH / 2 - m_vecSprites.back().getLocalBounds().width / 2,
SCREEN_HEIGHT / 2 - m_vecSprites.back().getLocalBounds().height / 2);
m_vecSprites.back().setColor(sf::Color(255, 255, 255, 0)); // Opacity : 100%
}
一切正常。问题出在哪里?我尝试了不同的方法,但效果总是相同的。谢谢!
原因是来自向量的实现。创建向量时,它会分配固定大小的内存,例如,向量的初始化大小为 A。当你将元素推入向量并且大小达到A时,矢量会自动重新分配另一个大小为2*A的连续内存块,如果它不能在同一地址重新分配大小为2*A的内存块,它将分配一个新的内存块并将旧内存中的内容复制到新内存中。
所以在你的第一个循环中:
m_vecSprites.back().setTexture(m_vecTextures[i]);
从您提供的链接中,函数"setTexture"的定义是:
void Sprite::setTexture(const Texture& texture, bool resetRect)
{
// Recompute the texture area if requested, or if there was no valid texture & rect before
if (resetRect || (!m_texture && (m_textureRect == sf::IntRect())))
setTextureRect(IntRect(0, 0, texture.getSize().x, texture.getSize().y));
// Assign the new texture
m_texture = &texture;
}
成员变量 'm_texture' 是指针类型
functon 'setTexture' 获取对 m_vecTextures[i] 的引用,但由于向量 'm_vecTextures' 仍然会增加,如果达到初始大小,向量将调整大小并移动内存块,并且引用可能变得有效。
如果向量初始化大小为 INTRO_LOGO_COUNT,则第一个循环将正常工作。
根据从 API 收集的信息进行更新
首先,您不应该为此使用sprintf
。 sprintf
是非常不安全的,如果你不小心,你可以很容易地缓冲溢出。如果你要坚持使用C函数,至少使用snprintf
。 其次,您不会自己清理字符串,也不会在任何地方放置 NULL 终止符。 这很容易导致未定义的行为。
你在C++所以使用字符串流,省去你的自私努力
我会把它写成,尽管我个人会使用移动语义,或者复制构造函数,而不是继续在"后面"编辑对象......但那只是我
其次,它被保留为参考并且您没有使用指针的事实意味着我们的指针无法更改......所以 Vector 不能使用,除非你能保证以后不会调整它的大小......如果您想使用矢量,请注意
m_vectTextures.reserve(INTRO_LOGO_COUNT); //reserves size so resize won't occur
for( int i = 0; i < INTRO_LOGO_COUNT; i++)
{
sf::Color color(255, 255, 255, 0); // Opacity : 100%
const char* prefix = "data/texture/intro/logo_";
const char* suffix = ".png";
std::stringstream ostr;
ostr << prefix << i << suffix;
std::string path( ostr.str() )
std::cout << path;
// if the above doesnt cut it, consider the same idea but using snprintf to read the 3 characters you need instead of an entire buffer
m_vecTextures.push_back( sf::Texture() );
sf::Texture& texture = m_vecTextures.back();
texture.loadFromFile( path.c_str() ); //if you need a string
m_vecSprites.push_back( sf::Sprite() );
sf::Sprite& sprite = m_vecSprites.back();
sprite.setTexture(texture);
// Center
sprite.setPosition(
( SCREEN_WIDTH - sprite.getLocalBounds().width ) / 2,
( SCREEN_HEIGHT - sprite.getLocalBounds().height ) / 2 );
sprite.setColor( color );
//since you still aren't sure and I don't know a better way to check
std::cout << "sprite " << i << " is using texture of " << i
<< " which had a name of " << path << std::endl;
//if you have a getter to check any of this now would be a good time.
}
另类
- 使用指针向量
- 使用
list
或dequeue
而不是vector
- 迭代器的指针操作问题
- 如何通过使用 2 位或更多数字的 XOR 运算符来执行此操作C++问题
- 使用双包装器类进行位操作(C++、clang)修复性能下降问题
- 插入操作的二叉搜索树代码问题
- 在MySql中使用字符串操作函数有什么问题
- OpenCV - 基本操作 - 性能问题 [模式:发布]
- 在张量流中创建新操作时指定形状句柄的形状(输出张量的秩问题)
- 无论如何,避免浮点操作的最大在线点问题
- 如何修复问题中的"teminated due to timeout"错误 数组操作 |黑客兰克?
- COUT和特定的字符串长度算术操作C 的问题
- 访问新创建的操作时出现问题
- 基本字符串操作有问题 [c++, Visual Studio 2013]
- 涉及删除操作的 C++ 指针问题
- 如何理解C++并发操作中同类实例导致死锁的问题
- 按位操作出现问题
- 关于"无符号字符"和"移位"操作的迷你问题?
- 二进制与文本模式下的文件操作 -- 性能问题
- 在类中操作向量时遇到问题
- 有符号和无符号int、XNOR的位操作问题
- vbacom互操作问题