[英]Vector elements getting reset to default values
在我的 C++ 程序中,我有一個對象向量。 該向量中的某些對象將具有一個值為 0 的成員變量。 例子:
struct MyObject{
float a;
float b;
int c;
};
std::vector<MyObject> all_objects;
// Fill all_objects with various elements, some of which will have an `a` value equal to 0.
現在我試圖將a
非零的元素復制到另一個向量:
std::vector<MyObject> non_zero_objects(all_objects.size()); // Ensure we allocate enough memory
int non_zero_cnt = 0;
for (int i = 0; i < all_objects.size(); ++i) {
if (all_objects[i].a != 0.0) { // If the value of a is non-zero
// Copy exactly one MyObject from the source location to the destination
std::memcopy(non_zero_objects.data() + (non_zero_cnt * sizeof(MyObject)), // Destination
all_objects.data() + i, // Source
sizeof(MyObject))
non_zero_cnt++;
}
}
這一切都很好。
然而,我觀察到的是,一段時間后,我的non_zero_objects
向量的前幾個元素被重置為其默認構造值(a = 0,b = 0,c=0)!
例子:
all_objects = {MyObj(3,3,1), MyObj(2,3,2), MyObj(0,0,0),..., MyObj(1,4,5)}
non_zero_objects = {MyObj(0,0,0), ..., MyObj(0,0,0)}
Loop Iteration 1:
non_zero_objects = {MyObj(3,3,1), ..., MyObj(0,0,0)}
Loop Iteration 2:
non_zero_objects = {MyObj(3,3,1), MyObj(2,3,2), ...,MyObj(0,0,0)}
...
Some future iteration:
non_zero_objects = {MyObj(0,0,0), MyObj(2,3,2), ...,MyObj(0,0,0)} // The first object suddenly has default constructed values!
...
Even later iteration
non_zero_objects = {MyObj(0,0,0), MyObj(0,0,0), ...,MyObj(1,4,5)} // Now also the second object has default constructed values!
我不知道這里發生了什么。 我為 non_zero_objects 分配了足夠的non_zero_objects
,如果向量開頭的 memory 被程序的其他部分覆蓋,我應該得到的混雜值不完全是默認構造的 ZA8CFDE63031BD59EB266ZF
行為是一致的,因為它總是發生在同一個循環迭代中。
我會注意到這個過程在 2 個 MPI 啟動的過程中同時發生,但是每個都有自己的 memory 空間(正確嗎?)所以它應該不可能影響另一個 memory 空間。
使用 valgrind 運行也不會發現任何非法/越界寫入。 我什至已經為每個向量元素打印出 memory 的位置,並且在迭代之間沒有預期的變化。
所有答案已經在上面的評論中給出。 所以這是一個總結,所有的信用 go 給上述評論者。
首先,你的代碼有問題。 它甚至無法編譯。
然后,是的,我知道,這是允許的,但它不是std::vector
的預期用途來訪問其底層數據存儲並進行一些低級數據操作。
這最終會導致您的主要語義錯誤。 這和你對指針運算的誤解。
data
返回指向non_zero_objects
數據存儲區域的指針。 如果您閱讀過指針算法,那么您將了解到, (pointer+1) 的計算結果是地址 + sizeof(指針指向的東西)。
所以,如果在non_zero_objects.data() + (non_zero_cnt * sizeof(MyObjec))
non_zero_cnt 等於 2 那么結果地址是
所以,你寫到你分配的 memory 的末尾。 導致一個嚴重的錯誤。 您的程序很可能會崩潰。 你很幸運 id 沒有。
無論如何,完全不確定會發生什么。
解決方案是,使用為此目的設計的 function。 在您的情況下,它是std::copy_if
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.