簡體   English   中英

將值循環分配給字符指針數組

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM