typedef struct MyStruct {
unordered_set<int> mySet;
}MyStruct;
int main(){
unordered_set<int> sset{ 1,2,3,4,5 };
MyStruct tk;
tk.mySet = sset; //This works fine.
for (auto x : tk.mySet) printf("%d ", x);
MyStruct *Arr = (MyStruct *)malloc(10* sizeof(MyStruct));
Arr[0] = tk; // This isnt working, giving an exception
//the same code runs as expected on codeblocks
for (auto x : Arr[0].mySet) printf("%d ", x);
return 0;
}
这是我在运行调试器时遇到的异常。
<fileName>.exe!std::list<int,std::allocator<int> >::_Orphan_ptr(std::_List_node<int,void *> * _Ptr) Line 1919 C++ <fileName>.exe!std::list<int,std::allocator<int> >::clear() Line 1501 C++ <fileName>.exe!std::_Hash<std::_Uset_traits<int,std::_Uhash_compare<int,std::hash<int>,std::equal_to<int> >,std::allocator<int>,0> >::_Copy(const std::_Hash<std::_Uset_traits<int,std::_Uhash_compare<int,std::hash<int>,std::equal_to<int> >,std::allocator<int>,0> > & _Right) Line 843 C++ <fileName>.exe!std::_Hash<std::_Uset_traits<int,std::_Uhash_compare<int,std::hash<int>,std::equal_to<int> >,std::allocator<int>,0> >::operator=(const std::_Hash<std::_Uset_traits<int,std::_Uhash_compare<int,std::hash<int>,std::equal_to<int> >,std::allocator<int>,0> > & _Right) Line 291 C++ <fileName>.exe!std::unordered_set<int,std::hash<int>,std::equal_to<int>,std::allocator<int> >::operator=(const std::unordered_set<int,std::hash<int>,std::equal_to<int>,std::allocator<int> > & _Right) Line 187 C++ <fileName>.exe!main() [External Code] [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
最佳答案
MyStruct *Arr = (MyStruct *)malloc(10* sizeof(MyStruct));
以任何方式使用 *Arr
或 Arr[i]
都是格式错误的,不需要诊断,因为不存在 MyStruct
类型的对象在任何地方 Arr
点。简单地创建一个足够大的内存块来容纳一个对象并不会创建一个对象。
许多编译器允许您对普通的旧数据类型执行此操作,并且就好像它是已定义的行为一样(它不是,但它们允许这样做)。
对于任何编译器上的非 pod 类型,它都不能可靠地工作。
Arr[0] = tk; // This isnt working, giving an exception
//the same code runs as expected on codeblocks
未定义的行为有效并不能证明代码是正确的。
MyStruct *Arr = (MyStruct *)malloc(10* sizeof(MyStruct));
::new( (void*)&Arr[0] ) MyStruct( tk );
这是在不存在任何对象的位置构造作为 tk
拷贝的对象的正确方法。请注意,您负责手动销毁该对象。
您还可以:
for (int i = i; i < 10; ++i)
::new( (void*)(Arr+i) ) MyStruct{};
并在每个“MyStruct
大小的孔”中构造一个对象。然后
Arr[0] = tk;
将是合法的。
for (auto x : Arr[0].mySet) printf("%d ", x);
return 0;
返回之前,出于理智考虑,您应该销毁您创建的每个对象。
Arr[0].~MyStruct();
如果你只构建了一个,或者
for (int i = 0; i < 10; ++i)
Arr[i].~MyStruct();
如果你构建了所有 10 个。
旁白:
关于是否可以采用大小为 10 的缓冲区 MyStruct
并将其视为数组的标准是否有点模棱两可,存在一些争论;但是,如果无法做到这一点,大多数人会认为这是一个缺陷。
作为一般规则,您不想使用 malloc
的数据来保存非 POD 类型。只需调用 new MyStruct[10]
即可。
关于c++ - Visual Studio unordered_set 异常,适用于 Codeblocks,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43764385/