C语言用循环初始化char*数组时所有元素指向同一地址如何解决
为什么C语言循环内定义的局部数组赋值给指针数组后所有指针指向同一块内存?
问题原因
你定义的char card[100]是栈上的局部自动变量,它的作用域仅限内层for循环的每次迭代块:
- 每次循环迭代时,系统都会在栈的相同位置为
card分配内存(因为每次迭代结束后这块内存就被释放,下一次迭代直接复用同一块栈空间) - 你直接把
card的地址赋值给deck[deckIndex],相当于所有deck元素都保存了这个栈地址的指针 - 循环结束后,
card的内存已经超出作用域,访问属于未定义行为,刚好这块内存最后一次写入的是Doce de oro,所以所有指针读出来都是同一个内容
修复方案
有两种常用改法,都不需要手动声明40个数组:
方法1:堆内存动态分配
每次循环时用malloc申请独立的堆内存存储牌面字符串,注意程序结束前要手动释放避免内存泄漏:
#define __USE_MINGW_ANSI_STDIO 1 #include <stdlib.h> #include <stdio.h> #include <string.h> int main(void) { char *type[4]= {"copas", "basto", "espada", "oro"}; char *number[10]= {"Uno", "Dos", "Tres", "Cuatro", "Cinco", "Seis", "Siete", "Diez", "Once", "Doce"}; char *deck[40]; int deckIndex= 0; for (int i = 0; i < 4; i++) { for (int j = 0; j < 10; j++) { // 申请100字节的堆内存,生命周期到free为止 char *card = malloc(100); strcpy(card, number[j]); strcat(card, " de "); strcat(card, type[i]); deck[deckIndex]= card; deckIndex++; } } for (int i = 0; i < 40; i++) { printf("%s\n", deck[i]); // 打印完释放内存 free(deck[i]); } return 0; }
方法2:直接在deck里预分配数组空间
把deck定义为二维字符数组,直接在对应位置写入内容,不需要动态分配:
#define __USE_MINGW_ANSI_STDIO 1 #include <stdio.h> #include <string.h> int main(void) { char *type[4]= {"copas", "basto", "espada", "oro"}; char *number[10]= {"Uno", "Dos", "Tres", "Cuatro", "Cinco", "Seis", "Siete", "Diez", "Once", "Doce"}; // 预分配40个长度为100的字符数组空间 char deck[40][100]; int deckIndex= 0; for (int i = 0; i < 4; i++) { for (int j = 0; j < 10; j++) { strcpy(deck[deckIndex], number[j]); strcat(deck[deckIndex], " de "); strcat(deck[deckIndex], type[i]); deckIndex++; } } for (int i = 0; i < 40; i++) { printf("%s\n", deck[i]); } return 0; }
推荐问题标题
《C语言循环内局部字符数组赋值给指针数组后所有元素内容相同的原因及解决方案》
内容的提问来源于stack exchange,提问作者Fullaccess
相关产品推荐
相关产品推荐

