[英]Why use memset in this case
我從以前退休的開發人員那里繼承了一些代碼。 我的問題具體是在以下場景中使用 memset。 不是 c 程序員,我想知道為什么在這種特殊情況下使用 memset,下一行代碼將值存儲在 memset 剛剛設置為全 0 的變量中。 是否有理由在 strcpy 之前使用 memset?
switch(argc)
{
case 1 :
printf("\nCommand: %s \n",argv[0]);
break;
case 2 :
memset(program_input_string,0,sizeof(program_input_string));
strcpy(program_input_string,argv[1]);
printf("\nCommand: %s [%s] \n",argv[0],argv[1]);
break;
default :
printf("\nCommand: %s \n",argv[0]);
}
事實上,在這種情況下使用memset
+ strcpy
的理由為零。 事實上,如果程序員想要確保剩余的字節被清零,那么應該使用帶有條件的strncpy
來測試字符串是否完全適合緩沖區:
strncpy(program_input_string, argv[1], sizeof program_input_string);
// if the last character in the array is not '\0', it means that the
// string did not fit into the array in its entirety, and perhaps
// the only sensible course of action is to abort the program...
if (program_input_string[sizeof program_input_string - 1] != '\0') {
fputs("The argument was too long!", stderr);
exit(1);
}
這有兩個明顯的優點:它不會將初始序列不必要地設置為零,並且它不會溢出輸入緩沖區 - 如果緩沖區溢出發生,它將退出並顯示合理的錯誤消息和退出代碼。
因此,對“為什么使用這種結構”這個問題的明確答案將是非常常見的“程序員無能”。
這可能是不必要的,但您應該在刪除它之前仔細檢查。
memset()
確保終端\0
之后的任何字節都被清零。 如果program_input_string
始終被讀取為字符串,並且代碼在到達\0
時始終停止,那么后面的內容並不重要。
如果有從整個緩沖區讀取的代碼(包括尾隨字節),這可能會很有用。 例如,如果所有sizeof(program_input_string)
字節都被復制到網絡數據包中並通過網絡發送,您就不想傳輸未初始化的字節。 在這種情況下,將緩沖區歸零是值得的。
我想知道為什么在這種特殊情況下使用 memset,下一行代碼將值存儲在 memset 剛剛設置為全 0 的變量中。 是否有理由在 strcpy 之前使用 memset?
提供的特定memset()
調用將目標數組的每個字節設置為 0。 strcpy()
調用成功后,僅覆蓋argv[1]
字符串中的字節數,包括可能更少的終止符。 這種區別實際上對程序是否重要,無法從提供的代碼中確定。
另請注意,所提供的代碼可能會出現緩沖區溢出——它實際上是該問題的典型案例之一。 如果argv[1]
比目標數組長,則會出現未定義的行為。
在這種情況下,調用 memset 是多余的。 你可以寫
strcpy(program_input_string,argv[1]);
因為 function strcpy 也會復制目標字符串中的終止零。
作為一個想法,有時一個字符數組需要包含幾個字符串。 在這種情況下,兩個連續的零表示存儲在字符數組中的字符串集的結尾。 所以需要用零初始化數組。
假設數組program_input_string
已經包含字符串
ABC\0DEF\0\0
那么如果復制字符串 E 你會得到
E\0C\0DEF\0\0
正如所見,結果不是預期的。 現在數組包含一組三個字符串而不是一個字符串。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.