![](/img/trans.png)
[英]When using a SAST tool, why do we have to use a "build wrapper" for compiled languages (e.g. C/C++)?
[英]Why and when do we have to initialize a string before using in C++?
我正在閱讀一些C ++教程,發現有時會初始化字符串(“ initialized”可能不是正確的術語),有時卻沒有。
為什么以及何時?
我正在閱讀的代碼是:
char name[50];
char lastname[50];
char fullname[100];
...
cin.getline ( name, 50 );
...
cin.getline ( lastname, 50 );
fullname[0] = '\0'; // strcat searches for '\0' to cat after
strcat ( fullname, name ); // Copy name into full name
strcat ( fullname, " " ); // We want to separate the names by a space
strcat ( fullname, lastname ); // Copy lastname onto the end of fullname
請有人解釋。
在C ++中,有字符數組,如char name[50]
,還有字符串類,如std::string
。
字符數組根據它們在C中的相同規則進行初始化-也就是說,如果它們是堆棧變量,則不進行初始化;如果是靜態/全局變量,則在加載時將其初始化為零-但是有例外基於系統細節,因此最好是假設它們從未初始化。
字符串類(如std :: string)在對象的構造函數階段被初始化-因此它們總是被初始化。
在您的特定代碼中,您正在使用固定長度的字符數組。 它們通常以null終止,但可能並不總是-特別是cin.getline ( name, 50 );
將讀取完整的50個字符,並且如果輸入的字符數少於或等於49個,則該數據將以null終止,但是由於沒有空間可容納50個以上的字符,因此如果輸入的字符數為50個或更多,則不會以null終止-這會對您的strcat
產生影響,因為strcat
假定數據以null結尾-您必須使用strncat
來確保代碼安全。
與其他任何數據類型一樣。 默認情況下,局部變量包含垃圾值。 因此,如果要讀取其值,則可以對其進行初始化。 但是,如果您知道將要寫入變量,則可以跳過初始化部分。
例如:
char a[20]; //local variable
包含垃圾,因此您需要在讀取之前向其中寫入一些有意義的數據。 但是,如果您只寫它,則可以跳過初始化。
您所擁有的在堆棧上有一個分配。 編譯器不保證分配的內存為空,因此您可以在其上放置垃圾,這就是為什么您需要填充0來清除垃圾的原因。
你可以做到
memset(pointer, '0', size);
例
char a[50]
memset(a, NULL, sizeof(char)*50);
當取決於您的操作時,如果您想在其中寫入一些數據並進行讀取,則\\ 0可能會節省您的時間,因為這是截止日期;如果您想讀取所有數據,則將50字節char a [50]設置為char忽略\\ 0,因此您需要清除數據。 解決方法是清除^^內部的數據。
first_name
和last_name
不會立即初始化,因為接下來的兩行會在after和full_name
到0終止符后立即對其進行初始化,因此它將表示一個空字符串,可以將其與std :: strcat連接。
char first_name[50];
char last_name[50];
// There is no need to initialize first_name and last_name,
// they will contain garbage as with any uninitialized values but they get
// overwritten here when reading from stdin anyways.
cin.getline ( first_name, 50 );
cin.getline ( last_name, 50 );
char full_name[100];
// Again full_name contains garbage, so it gets a 0 terminator here in order
// to have it represent an empty string.
full_name[0] = '\0';
// full_name had to be an empty string in order to concatenate
// onto it using strcat
strcat ( full_name, first_name );
strcat ( full_name, " " );
strcat ( full_name, last_name );
話雖這么說,這些都是C樣式的字符串,您很可能更喜歡只使用std::string
。
cin.getline
不使用或檢查您傳入的緩沖區的原始值,因此對於該功能,無需初始化緩沖區。
相比之下, strcat
檢查現有緩沖區的內容,以確定應在指定的字符串字符上附加的位置。 因此,使用strcat
,不僅必須隨意初始化緩沖區,而且還必須初始化一些零字節來標記邏輯字符串末尾位置。
正如其他人所說,顯示的代碼非常不安全。 這是不安全的,因為(我在撰寫本文時尚未對此進行評論)維護程序員可能沒有意識到full_name
具有確切的緩沖區大小來容納最大長度的名字,空格和最大大小的姓氏。 至少應該在評論中對此進行了解釋。
但是比注釋更好,應該使用更安全的長度檢查功能。
並且除了學習之外,更好的方法是使用諸如std::string
類的字符串類。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.