You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中如何将字符串存入字符指针数组?及异常问题排查

问题排查与解决方案

嘿,这问题我太熟了!你这是踩了C语言里局部变量内存生命周期的大坑啦。咱们一步步拆解:

问题根源

你在init_NFA_table函数里定义的char input[]是栈上的局部变量,它的内存空间只有在函数执行时才有效,函数结束后这块内存会被系统回收(或者被后续操作覆盖)。更关键的是:

  • 如果是在循环中重复使用这个input数组读取输入,每次循环都会复用同一块栈内存;
  • 你把input的地址直接赋值给NFAtab[x][y],导致所有指针数组的元素都指向了同一块内存区域;
  • 最后这块内存里留存的是你最后一次输入的字符串,所以打印时所有位置都显示最后那个值。

举个错误代码的典型例子(对应你遇到的场景):

char *NFAtab[STATES][SYMBOLS];

void init_NFA_table() {
    char input[20]; // 局部栈数组,每次循环复用同一块内存
    for (int x = 0; x < STATES; x++) {
        for (int y = 0; y < SYMBOLS; y++) {
            scanf("%s", input);
            NFAtab[x][y] = input; // 错误:所有元素指向同一个地址
        }
    }
}

三种解决方案

1. 动态分配内存(最灵活)

每次读取输入后,用strdup()(或malloc+strcpy)复制字符串到新分配的堆内存中,把新内存的地址赋值给指针数组元素。这样每个元素都有独立的内存空间,不会互相影响。

示例代码:

#include <string.h> // 包含strdup所需头文件
#include <stdlib.h> // 包含malloc/free所需头文件

char *NFAtab[STATES][SYMBOLS];

void init_NFA_table() {
    char input[20];
    for (int x = 0; x < STATES; x++) {
        for (int y = 0; y < SYMBOLS; y++) {
            scanf("%s", input);
            // 用strdup复制字符串,自动分配内存
            NFAtab[x][y] = strdup(input);
            // 或者手动malloc+strcpy(兼容性更好)
            // size_t len = strlen(input) + 1;
            // NFAtab[x][y] = malloc(len);
            // if (NFAtab[x][y] != NULL) {
            //     strcpy(NFAtab[x][y], input);
            // }
        }
    }
}

// 记得在程序结束前释放内存,避免泄漏
void free_NFA_table() {
    for (int x = 0; x < STATES; x++) {
        for (int y = 0; y < SYMBOLS; y++) {
            free(NFAtab[x][y]);
        }
    }
}

2. 使用二维字符数组(最省心)

如果你能提前确定字符串的最大长度,可以把NFAtab定义成二维字符数组,直接用strcpy复制字符串,避免指针操作的坑。

示例代码:

#define MAX_STR_LEN 20 // 根据你的需求调整长度
char NFAtab[STATES][SYMBOLS][MAX_STR_LEN];

void init_NFA_table() {
    char input[MAX_STR_LEN];
    for (int x = 0; x < STATES; x++) {
        for (int y = 0; y < SYMBOLS; y++) {
            scanf("%s", input);
            strcpy(NFAtab[x][y], input); // 直接复制字符串到数组元素
        }
    }
}

注意:要确保MAX_STR_LEN足够大,避免字符串截断或缓冲区溢出。

3. 使用静态数组(不推荐,仅特殊场景)

把input定义成static char input[],这样它的内存会放在静态存储区,函数结束后不会被释放。但要注意:静态数组每次循环还是会被覆盖,所以如果是多次读取输入,还是会出现后续值覆盖之前的情况,只有单次赋值时适用,灵活性很差。

关键提醒

  • 用动态分配内存时,一定要记得在程序结束前调用free释放内存,否则会造成内存泄漏;
  • 如果使用strdup,要确认你的编译环境支持(大部分POSIX系统都支持,Windows下可能需要自行实现);
  • 用二维字符数组时,务必预留足够的空间存储字符串结束符\0。

内容的提问来源于stack exchange,提问作者raultds

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:49:49