[英]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數組。 您需要修復一些問題:
由於portarray被聲明為指針數組,因此需要單獨的緩沖區指向。
將portarray更改為聲明為std :: string的數組。 您會得到一份副本。 因此,您將擁有不同的價值。
將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.