簡體   English   中英

向量元素重置為默認值

[英]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 給上述評論者。

首先,你的代碼有問題。 它甚至無法編譯。

  • 備忘錄。 正確的 function 名稱是 std::memcpy
  • memcopy后沒有分號
  • 定義 MyObject 並使用 MyObj 進行初始化
  • MyObj 的構造函數使用錯誤。

然后,是的,我知道,這是允許的,但它不是std::vector的預期用途來訪問其底層數據存儲並進行一些低級數據操作。

這最終會導致您的主要語義錯誤。 這和你對指針運算的誤解。

data返回指向non_zero_objects數據存儲區域的指針。 如果您閱讀過指針算法,那么您將了解到, (pointer+1) 的計算結果是地址 + sizeof(指針指向的東西)。

所以,如果在non_zero_objects.data() + (non_zero_cnt * sizeof(MyObjec)) non_zero_cnt 等於 2 那么結果地址是

  • (數據) + (2 * 12)
  • 數據 + 24
  • --> {數據 + 288}

所以,你寫到你分配的 memory 的末尾。 導致一個嚴重的錯誤。 您的程序很可能會崩潰。 你很幸運 id 沒有。

無論如何,完全不確定會發生什么。

解決方案是,使用為此目的設計的 function。 在您的情況下,它是std::copy_if

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM