我剛剛開始學習C 。現在我正在學習陣列。所以我正在嘗試不同的例子。下面給出了一個這樣的例子:
int main()
{
const char *ptr1 = "Anya";
char arr[] = {'A','n','y','a'};
std::string name1(ptr1); //this works
std::cout << name1 << std::endl;
std::string name2(arr);
std::cout << name2 << std::endl; //this prints extra characters at the end?
return 0;
}
在上面最后一條cout陳述句的示例中,我在最后得到了一些額外的字符。我的問題是,我怎樣才能防止在上面的代碼中發生這種情況以及代碼有什么問題,以便我以后不會犯同樣的錯誤?
uj5u.com熱心網友回復:
char arr[] = {'A','n','y','a'};不是以空值終止的,因此您在創建字串時會越界讀取它,這反過來會使您的程式具有未定義的行為(因此可以做任何事情)。
要么讓它空終止:
char arr[] = {'A','n','y','a','\0'};
或者,從迭代器創建字串:
#include <iostream>
#include <iterator>
#include <string>
int main() {
char arr[] = {'A', 'n', 'y', 'a'};
std::string name2(std::begin(arr), std::end(arr));
std::cout << name2 << '\n'; // now prints "Anya"
}
或者使用將長度作為引數的建構式創建它:
std::string name2(arr, sizeof arr); // `sizeof arr` is here 4
uj5u.com熱心網友回復:
問題是您正在構造一個使用std::string非空終止陣列,如下所述。
當你寫道:
char arr[] = {'A','n','y','a'}; //not null terminated
上面的陳述句創建了一個非空終止的陣列。
接下來當你寫:
std::string name2(arr); //undefined behavior
關于上述宣告,有兩點需要注意:
arrchar*由于型別衰減而衰減為 a 。- 這
char*作為引數傳遞給具有型別引數的std::string建構式const char*。本質上,上面的陳述句從非空終止陣列創建一個std::string物件。
但請注意,每當我們std::string使用 a創建 a 時const char*,指標指向的陣列必須為空終止。否則結果是未定義的行為。
未定義的行為意味著任何事情1都可能發生,包括但不限于給出預期輸出的程式。但永遠不要依賴(或基于)具有未定義行為的程式的輸出。
例如,這里程式給出了預期的輸出,但這里沒有。所以正如我所說,不要依賴具有 UB 的程式的輸出。
解決方案
您可以通過使陣列為空終止來解決此問題,如下所示。
char arr[] = {'A','n','y','a','\0'}; //arr is null terminated
// char arr[] = "Anya"; //this is also null terminated
1有關未定義行為的更技術上準確的定義,請參見此處提到:對程式的行為沒有限制。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/415292.html
標籤:
下一篇:通過HTML+CSS+JavaScript實作滑鼠移動到頁面頂部導航欄出現,如果移出導航欄3秒又隱藏起來,而且不受滾動條影響(二)
