2013-05-16 90 views
0

考慮這段代碼。將值從一個向量複製到另一個向量(從書本)

#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循環中的代碼)?「

我無法回答任何這些問題,所以有一點幫助將不勝感激。

在此先感謝。

+2

你有你的想法任何想法'test'應包含哪些內容?無論如何,這本UB代碼在書中做了些什麼? – chris

+0

題目是指針,所以我想這是學習 –

+2

有教學指針更好的方式,其中最重要的是沒有機會炸掉你的計算機程序。 – chris

回答

4

該代碼引入懸掛指針。在循環體看起來是這樣的:

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

局部變量n作爲循環體結束,一旦失去範圍,使指針&n現在是一個懸擺指針。如果碰巧test只包含2,那麼未定義的行爲就是隨機出來的。

如果你想「適當」到test數據複製,可以將for循環體改成這樣:

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

請走「正常」與一粒鹽...

+0

所以如何改變循環? –

+0

@KudayarPirimbaev剛剛編輯包括。 –

+0

,謝謝,我知道這一點,但它僅僅是學習的目的,我不會用這種風格反正 –

1

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

我不明白什麼運動是試圖做(爲什麼它例如使用指針的載體),所以我可以怎樣解決這個問題真正的幫助不是。你可以做到這一點

一種方式是按值進行test店:

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

隨後的push_back更改爲類似test.push_back (n);最後的打印語句現在刪除 - 不需要*運營商。

編輯點評:

首先,我懷疑這本書的:它不應該表現出不確定的行爲或原始指針單內建類型。但你可以改變你的循環體,如果你想:

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

注意,這兩者都會導致內存泄漏,除非你以後delete這些指針,該存儲由值消除了問題。

+0

我不能改變任何東西,除了循環 –

1

你推兩個相同的指針ntest陣列。 n等於你的第一個數組的最後一個元素。請注意,控制流退出循環後,所有指向n的指針都將失效。所以,實際上你的test數組包含無效的指針,而不是指向2的指針。

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

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

還要注意的是,你有內存泄漏在這裏。應使用delete以後銷燬使用new創建的每個int。

0

1)我認爲這個問題的前提是錯誤的。該循環向test添加兩個元素,每個元素包含自動變量n的地址,其範圍僅限於循環的主體。不能保證n在循環中都會被分配到相同的內存位置,但我想大多數編譯器可能會在兩遍中重複使用相同的位置。

此外,n超出範圍的輸出語句。因此,將這些存儲器位置的test中的指針引用未定義。同樣,它們很可能仍會包含循環中分配的值。

因此,只有在循環的第二遍中將相同的位置重用爲n並且該位置在輸出語句執行時未被覆蓋時,輸出將爲「2 2」。這些房屋都不能保證。

2)爲了得到輸出「1 2」無外循環改變任何東西,一個可以改變的nint& n = *v[i]的定義,這將是從給定的代碼的單個字符的變化,但最終的結果是相當奇怪。

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

相關問題