簡體   English   中英

我的for循環使每個值成為最后一個值(C ++)

[英]my for loop is making every value the last value (C++)

我有一個用戶輸入一個值,然后根據該值和以下31個值定義端口。 這些端口然后應存儲在數組中,但是出於某種原因,當我從數組中調用時,每個值都是最后一個值。 (例如,如果用戶輸入5000,則數組中的每個值最終都是5031)。 將實際數字存儲在數組中是有問題的,因為如果我在創建值時將其打印出來,它們都是正確的。 不好意思的代碼,我是新手。 謝謝!

//enter own ports   
using namespace std;
    cout << "enter a port number between 1000-9999: "; // gets port from user input
    cin >> startingport;


for (int i=0; i<32; i++) // defines 32 ports starting with user input
    {
    sprintf(portchar, "%d", startingport+i);
    cout << "defining port: " << portchar << endl; // gives correct value
    portarray[i] = portchar;
    }

cout << portarray[0] << endl; // gives incorrect value

抱歉,應該在此之前-我在另一個文件中有定義。 我需要port成為角色,因此portchar

static int startingport;
static char portchar[6];
static char *portarray[32];

當您反復使用“ portchar”進行打印時,它們將指向相同的基礎值,而它恰好是靜態char。

portarray [0]-> portarray [1]-> ... portarray [2]->所有都指向“ portchar”

它們都指向共享char數組。 您需要修復一些問題:

  1. 由於portarray被聲明為指針數組,因此需要單獨的緩沖區指向。

  2. 將portarray更改為聲明為std :: string的數組。 您會得到一份副本。 因此,您將擁有不同的價值。

  3. 將portarray保留為指針數組,但是,為循環的每次迭代分配一個新的portchar並存儲這些指針。

_3不好,因為您必須自己管理內存。

_2更好,並且將std :: vector <>用於portarray。

_1正在生成字符串的副本,您需要確定是否要支付該費用。

首先,我想回應Mike Seymour的評論,即您應該使用std::string s和一個容器,而不是char**char[] 更高級別的抽象有助於減輕許多與指針管理和算術相關的常見問題。

就是說,這是一個很好的教學時間。

什么地方出了錯

讓我們開始告訴自己,指針( * )只不過是一個地址。 就像我住在第一街555號一樣,內存中的所有對象都有一個地址。 如果我搬出我的住址而其他人搬進去,當有人問誰住在第一街555號時,那一刻的答案將是搬進來的人, 而不是我。

如果指針只是地址,那么指針數組是什么? 好吧,這只是地址列表! 想象一個帶有空槽的列表,該列表可以容納32個地址。 這就是portarray

那你的循環做什么? 好吧,這里有三個基本操作:

sprintf(portchar, "%d", startingport+i);

這相當於有人進入了地址portchar 地址仍然相同,現在有一些新內容。

cout << "defining port: " << portchar << endl;

這與詢問誰住在該地址相同。 當然,您知道這是什么,這只是startingport+1因為startingport+1剛剛移入!

最后:

portarray[i] = portchar;

請密切注意這一點。 這表示將地址portchar復制到您的地址列表中。 假設您有一張紙,然后寫下了"0: 555 First St" 不是復制那個地址的人,而是復制地址本身。 此循環的下一個迭代,當需要再次寫下該地址時,我們將寫入"1: 555 First St" ,與之前相同。

因此,在循環結束時,您將獲得一個不錯的地址列表,並且所有地址都完全相同,因為當然您實際上從未真正更改過循環中的地址

您可以做什么(不使用std::string

如果您願意手動管理portarray指向的內存,則可以使用堆分配的內存來解決問題。 這是必需的,因為您需要可以將32唯一地址放入portarray 您靜態分配的portchar給您一個地址不足。

// Assuming you've removed your portchar declaration
for (int i=0; i<32; i++) // defines 32 ports starting with user input
{
    portarray[i] = new char[6]; // This dynamically allocates memory
    sprintf(portarray[i], "%d", startingport+i);
    cout << "defining port: " << portarray[i] << endl; // gives correct value
}

cout << portarray[0] << endl; // gives correct value

要稍后釋放內存,您必須執行以下操作:

for (int i=0; i<32; i++)
{
    delete[] portarray[i];
}

看起來很亂,那是因為。 正如其他人所建議的那樣,您可以通過使用std::string和container來避開這個雷區。 如果您的代碼適合這些抽象,我強烈建議您使用它們。

暫無
暫無

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

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