And*_* T. 2 c++ debugging g++ c++17
我一直试图追踪一个错误超过10个小时,到现在为止我开始认为这个错误不在我身边.但是,我觉得可能是我只是忘记或误解了某些东西.
我有一个类型为std :: vector的类成员,名为temp_materials,在构造函数内部(当temp_materials仍为空时),此代码运行:
Material &stonewallbug = temp_materials.emplace_back(resource_lib.get_shader("DeferredGeometryShader"));
stonewallbug.set_texture("texture_diffuse1", resource_lib.get_texture("StonewallDiffuse"));
stonewallbug.set_texture("texture_specular1", resource_lib.get_texture("StonewallSpecular"));
Material &containerbug = temp_materials.emplace_back(resource_lib.get_shader("DeferredGeometryShader"));
containerbug.set_texture("texture_diffuse1", resource_lib.get_texture("ContainerDiffuse"));
containerbug.set_texture("texture_specular1", resource_lib.get_texture("ContainerSpecular"));
Material stonewall1 = temp_materials[0];
Material container1 = temp_materials[1];
Material stonewall2 = stonewallbug;
Material container2 = containerbug;
Run Code Online (Sandbox Code Playgroud)
如果在复制过程中没有出错,那么stonewall1的内容应该等于stonewall2,容器1到容器2应该是正确的吗?
但是,然后我将所有这些插入到一个简单的向量中,其内容将在稍后呈现:
// Using temp_materials[0]
auto stonewall1node = SceneNode(stonewall1, resource_lib.get_mesh("Cube"));
stonewall1node.set_transform(glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f)));
m_scene_list.push_back(stonewall1node);
// Using temp_materials[1]
auto container1node = SceneNode(container1, resource_lib.get_mesh("Cube"));
container1node.set_transform(glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 1.0f)));
m_scene_list.push_back(container1node);
// Using stonewallbug
auto stonewall2node = SceneNode(stonewall2, resource_lib.get_mesh("Cube"));
stonewall2node.set_transform(glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 1.0f, 0.0f)));
m_scene_list.push_back(stonewall2node);
// Using containerbug
auto container2node = SceneNode(container2, resource_lib.get_mesh("Cube"));
container2node.set_transform(glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 1.0f, 1.0f)));
m_scene_list.push_back(container2node);
Run Code Online (Sandbox Code Playgroud)
现在,我希望有2个"容器"立方体相互堆叠,2个"石墙"立方体堆叠在一起,但这是我得到的结果:
但是,如果我将线路移动Material stonewall2 = stonewallbug;到stonewallbug和containerbug的创建之间,我会得到我期望的结果.
注意到这一点,我做了一个非常非常简单的C++程序:
#include <iostream>
#include <vector>
#include <string>
int main() {
std::vector<std::string> strings;
std::string& ref1 = strings.emplace_back("1");
std::string& ref2 = strings.emplace_back("2");
std::cout << "ref1: " << ref1 << std::endl;
std::cout << "ref2: " << ref2 << std::endl;
std::cout << "strings[0]: " << strings[0] << std::endl;
std::cout << "strings[1]: " << strings[1] << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
运行它时的结果是很多无意义的字符.但是,如果在安装ref2之前输出ref1,它会输出预期的结果.在这里,它说vector的emplace_back应该返回对插入元素的引用,但对我来说它似乎并不像它应该的那样工作.
我误解了什么,或者这只是g ++ 7.1中一个非常明显的错误?
编辑:我简直不敢相信我在这么明显的事情上花了这么多时间...... :)
您必须小心容器元素的引用和迭代器.各种变异容器操作使引用和迭代器无效.详细信息因容器和操作而异,但是,对于std::vector所有插入操作(例如push_back和emplace_back)以及除结束之外的任何其他操作的擦除,通常会使引用和迭代器无效(但请参阅下面的方法来避免这种情况).
因此,在以下代码中,
std::vector<T> v;
T & a = v.emplace_back(a, b, c);
T & b = v.emplace_back(x, y, z);
Run Code Online (Sandbox Code Playgroud)
第二次调用emplace_back使参考无效a.(通过无效引用访问对象具有未定义的行为.)
为避免a中的失效std::vector,请使用reserve和capacity设施:
std::vector<T> v;
v.reserve(2);
T & a = v.emplace_back(a, b, c);
T & b = v.emplace_back(x, y, z);
Run Code Online (Sandbox Code Playgroud)
如果new 小于或等于当前值,则末尾的插入不会失效.sizecapacity
| 归档时间: |
|
| 查看次数: |
384 次 |
| 最近记录: |