为何C语言指针数组lines的地址赋值操作未生效?
问题根源与解决方案
哦,这个问题我一眼就看到两个关键问题——先来说最直接导致你看到“lines地址没变化”的原因:数组越界访问!
1. 数组越界访问:你根本没写到目标数组里
你定义的指针数组lines大小是MAX_LINES(也就是20),这意味着它的有效索引范围是0到MAX_LINES-1(也就是0到19)。但你的代码里写的是:
lines[MAX_LINES+i]=line;
当i从0开始时,第一个索引就是20+0=20,这已经超出了lines数组的边界!你相当于在往lines数组后面的未知内存地址写数据,完全没碰lines数组本身的元素,所以lines的内容当然不会有任何变化。
2. 局部变量的生命周期陷阱:即使索引正确也会踩坑
就算你把代码改成lines[i] = line,这里还有一个严重的问题:line是for循环内部的局部自动变量,它存储在栈上。每次循环迭代时,这个变量的内存空间其实是被重复利用的(循环结束后变量销毁,下一次循环又占用同一个栈位置),所以最后所有lines里的指针都会指向同一个内存地址。更糟的是,当main函数执行完毕,栈上的line内存会被系统回收,这些指针就变成了野指针,后续访问会导致未定义行为。
修正方案
根据你的需求,有两种常见的修正方式:
方式一:动态分配内存(灵活可控)
为每个字符串单独分配堆内存,这样可以避免栈变量的生命周期问题:
#define MAX_LINES 20 #define MAX_LINE 20 #include <stdio.h> #include <stdlib.h> int main(){ char *lines[MAX_LINES]; for(int i=0;i<MAX_LINES;i++){ // 为每个字符串分配MAX_LINE大小的内存 char *line = malloc(MAX_LINE); if (line == NULL) { // 处理内存分配失败的情况 perror("malloc failed"); // 释放已经分配的内存,避免内存泄漏 for(int j=0;j<i;j++){ free(lines[j]); } return 1; } lines[i] = line; } // 这里可以对lines进行读写操作,比如用fgets读取输入 // ... // 记得最后释放所有动态分配的内存,避免泄漏 for(int i=0;i<MAX_LINES;i++){ free(lines[i]); } return 0; }
方式二:使用二维字符数组(无需手动管理内存)
如果字符串长度和行数都是固定的,直接用二维数组更简单:
#define MAX_LINES 20 #define MAX_LINE 20 #include <stdio.h> int main(){ char lines[MAX_LINES][MAX_LINE]; // 直接使用lines[i]存储字符串,比如读取用户输入 for(int i=0;i<MAX_LINES;i++){ printf("输入第%d行内容:", i+1); fgets(lines[i], MAX_LINE, stdin); } // 输出验证 for(int i=0;i<MAX_LINES;i++){ printf("第%d行:%s", i+1, lines[i]); } return 0; }
内容的提问来源于stack exchange,提问作者Berlios
相关产品推荐
相关产品推荐

