如何在C语言函数内部修改字符串数组?
如何在C语言函数内部修改字符串数组?
我完全理解你的困扰——在其他语言里很简单的操作,到C语言里因为内存管理的细节反而容易踩坑。咱们先把问题根源理清楚,再给你两种可行的解决方案:
问题根源
你在fillGenes函数里定义的newVal是局部栈数组,当函数执行完毕返回后,这块栈内存会被系统回收,此时genes[i]保存的就是已经失效的内存地址(也就是所谓的“悬空指针”),后续访问这些指针的行为属于未定义行为,程序很可能崩溃或者输出乱码。
另外你提到不能用strcpy,其实是因为你原来的genes数组里的元素指向的是字符串字面量,字符串字面量存储在只读内存区域,直接对它进行写入操作(比如strcpy)会触发未定义行为,这也是原代码不能直接用strcpy的原因。
解决方案1:使用动态内存分配(malloc)
我们可以在堆上为每个新输入的字符串分配内存,堆内存不会随着函数结束而释放,这样genes里的指针就能一直有效。记得使用完后要手动释放内存避免泄漏:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define GEN 3 void fillGenes(char **); int main() { char *genes[GEN] = {"Gen0", "Gen1", "Gen2"}; for (int i = 0; i < GEN; i++) { printf("%s\n", genes[i]); } fillGenes(genes); for (int i = 0; i < GEN; i++) { printf("%s\n", genes[i]); } // 释放动态分配的内存,避免内存泄漏 for (int i = 0; i < GEN; i++) { free(genes[i]); } return 0; } void fillGenes(char **genes) { printf("Introduce the name of %d genes.\n", GEN); for(int i = 0; i < GEN; i++) { printf("Name of gene %d\n", i); char newVal[10]; scanf("%s", newVal); // 分配足够的内存(包含字符串终止符'\0') genes[i] = malloc(strlen(newVal) + 1); // 检查内存分配是否成功 if (genes[i] == NULL) { perror("Failed to allocate memory"); exit(EXIT_FAILURE); } // 将输入的字符串复制到分配好的内存中 strcpy(genes[i], newVal); } }
解决方案2:提前分配可修改的缓冲区(二维数组)
如果不想使用动态内存,可以在main函数里定义一个二维数组,每个元素都是固定大小的可写缓冲区,这样函数里直接用scanf或者strcpy写入即可:
#include <stdio.h> #include <string.h> #define GEN 3 #define MAX_GENE_LENGTH 10 // 定义每个基因名称的最大长度(包含终止符) void fillGenes(char (*genes)[MAX_GENE_LENGTH]); int main() { // 二维数组,每个元素都是可修改的缓冲区 char genes[GEN][MAX_GENE_LENGTH] = {"Gen0", "Gen1", "Gen2"}; for (int i = 0; i < GEN; i++) { printf("%s\n", genes[i]); } fillGenes(genes); for (int i = 0; i < GEN; i++) { printf("%s\n", genes[i]); } return 0; } void fillGenes(char (*genes)[MAX_GENE_LENGTH]) { printf("Introduce the name of %d genes.\n", GEN); for(int i = 0; i < GEN; i++) { printf("Name of gene %d\n", i); // 使用%9s限制输入长度,避免缓冲区溢出 scanf("%9s", genes[i]); } }
备注:内容来源于stack exchange,提问作者caravana_942
相关产品推荐
相关产品推荐

