簡體   English   中英

將值從一個向量復制到另一向量(從書本復制)

[英]Copying values from one vector to another (from book)

考慮這段代碼。

#include <iostream>
#include <vector>

using namespace std;


int main()
{
    vector <int *> test;
    vector <int *> v;
    int *a = new int;
    int *b = new int;
    *a = 1;
    *b = 2;
    v.push_back (a);
    v.push_back (b);
    for (int i = 0; i < 2; ++i)
    {
        int n = *v[i];
        test.push_back (&n);
    }
    cout << *test[0] << " " << *test[1] << endl;
    delete a;
    delete b;
    return 0;
}

問題的陳述是:

“鑒於此代碼,請回答以下問題:

  1. 為什么“測試”向量僅包含2?

  2. 我們如何更改for循環以正確復制(僅for循環內的代碼)?”

我無法回答任何這些問題,因此將不勝感激。

提前致謝。

該代碼引入了懸空指針。 循環的主體如下所示:

{
    int n = *v[i];
    test.push_back (&n);
}

循環體結束時,局部變量n失去作用域,因此指針&n現在是懸空指針。 如果碰巧test僅包含2,那就是從未定義行為中隨機產生的結果

如果要“正確”復制數據以進行test ,可以將for循環體更改for

{
    int* n = new int;
    *n = *v[i];
    test.push_back (n);
}

請“適量”加一粒鹽。

第一個問題是一個技巧性的問題:向量包含指向不再存在的變量的指針,並且取消引用可能會導致幾乎任何輸出。 我想在某些機器和編譯器上它會打印所有2 s。

我不明白該練習正在嘗試做什么(例如,為什么要使用指針向量),所以我無法真正幫助解決問題。

一種方法是按值存儲test

首先將測試向量更改為vector <int> test;

然后將push_back更改為test.push_back (n); 最后是print語句,以刪除現在不需要的*運算符。

編輯評論:

首先,我懷疑這本書:它不應該顯示未定義的行為或指向單個內置類型的原始指針。 但是,您可以根據需要更改循環主體:

 for (int i = 0; i < 2; ++i)
 {
     int* n = new int;
    *n = *v[i];
     test.push_back (&n);
 }

請注意,除非您以后delete這些指針,否則這兩種情況都會導致內存泄漏,從而消除了按值存儲的問題。

您將兩個相同的指針推到ntest數組中。 n等於第一個數組的最后一個元素。 請注意,控制流退出循環后,所有指向n指針都將變為無效。 因此,實際上您的test數組包含無效的指針,而不是指向2s的指針。

您應該為每個整數創建一個副本:

int* n = new int(*v[i]);
test.push_back (n);

另請注意,此處內存泄漏。 使用new創建的每個int都應在以后使用delete銷毀。

1)我認為問題的前提是錯誤的。 循環添加了兩個要test元素,每個元素都包含自動變量n的地址,其范圍限於循環的主體。 不能保證在兩次循環中都將為n分配相同的內存位置,但是我想大多數編譯器可能會在兩次循環中重用相同的位置。

此外, n在輸出語句之外。 因此,未定義將test的指針引用到那些內存位置。 同樣,很有可能它們仍將包含循環中分配的值。

因此,僅當在循環的第二遍中將相同的位置重用n在執行輸出語句時該位置未被覆蓋時,輸出才為“ 2 2”。 這兩個場所均無法保證。

2)要獲得輸出“ 1 2”而不在循環外進行任何更改,可以將n的定義更改為int& n = *v[i] ,盡管最終結果是給定代碼的單個字符更改有點奇怪

一個更簡單的解決方案是消除臨時n並只需test.push_back(v[i])

暫無
暫無

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

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