[英]assigning values in loop to array of character pointers
我無法在循環中將值分配給char數組,因為它在每個數組值中都包含相同的值
例如,這有效
char* foo[3];
foo[0] = "mango"; foo[1] = "kiwi"; foo[2] = "banana";
int i=0; for(i=0;i<3;i++)
{
printf("%s\n",foo[i]);
}
但這不是,我也不明白為什么。
char* foo[3]; int i=0;
for(i=0;i<3;i++) {
char temp[5];
sprintf(temp,"VAL:%d",i);
foo[i] = temp;
}
for(i=0;i<3;i++)
{
printf("%s\n",foo[i]);
}
請幫助並提前感謝
第二個片段中的問題是foo
中的所有元素都指向同一個變量temp
,該變量在執行第二個for
時超出范圍,這是未定義的行為。 即使不超出范圍, foo
所有元素也會指向同一緩沖區,這是不正確的。
要更正,您需要復制temp
並將其存儲在foo
每個元素中。 這可以通過使用strdup()
來實現(如果沒有的話strdup()
(如果沒有malloc()
和strcpy()
):
for (i = 0; i < sizeof(foo)/sizeof(foo[0]); i++)
{
char temp[6];
snprintf(temp, sizeof(temp), "VAL:%d", i);
foo[i] = strdup(temp); /* Must be free()d later. */
}
或更改foo
的類型(如unwind所建議):
char foo[3][6];
int i;
for (i = 0; i < sizeof(foo)/sizeof(foo[0]);i++)
{
snprintf(foo[i], sizeof(foo[i]), "VAL:%d", i);
}
其他變化:
temp
的大小增加到6
因為它需要5
字符VAL:%d
加上 sprintf()
附加的空終止符。 因此,發布的代碼有緩沖區溢出。 snprintf()
避免緩沖區溢出。 sizeof(foo)/sizeof(foo[0])
來計算數組foo
的元素數量,而不是硬編碼元素計數。 您必須記住,在C中, char*
實際上並不存儲字符串,但是它存儲的內存地址將被視為字符串的第一個字符。
在您的第一個示例中, foo
數組的每個元素都持有不同的字符串字面量的地址。 在第二個示例中,使foo
數組的每個元素都指向局部變量temp
。 盡管循環中的每次迭代都會生成temp
的單獨實例,但任何明智的編譯器都會將所有這些實例放在彼此的頂部,從而提供您體驗到的結果。
解決方案是使用2D數組:
char foo[3][6]; int i=0;
for (i=0; i<3; i++) { sprintf(foo[i],"VAL:%d", i); }
for (i=0; i<3; i++) { printf("%s\n", foo[i]); }
或使用動態分配:
char* foo[3]; int i=0;
for (i=0; i<3; i++) { char* temp = malloc(6); sprintf(temp, "VAL:%d", i); foo[i] = temp; }
for (i=0; i<3; i++) { printf("%s\n", foo[i]); free(foo[i]); }
循環中的temp
變量可能在每次迭代中都重復使用相同的內存,因此最終您會將相同的地址寫入每個foo[]
插槽。 然后,更糟糕的是,退出循環時,該地址將變得無效,從而導致未定義的行為。
您需要動態分配每個字符串,或使用帶空格的字符串數組存儲實際字符串( char foo[3][20];
或其他內容)。
兩個問題:
1)您已將temp
聲明為char temp[5]
並且用超過4個字符填充了它:
sprintf(temp,"VAL:%d",i);
通過使sprintf超出數組末尾進行寫操作,因為它必須寫終止\\0
2)變量temp
是for循環的局部變量,一旦循環結束,它將超出范圍。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.