C语言从用户输入创建字符串一维数组出现重复值和段错误问题求解
问题原因
- 你定义的
char temp[32]是create_array函数内的栈局部变量,整个函数执行过程中,所有循环迭代里的temp都占用同一块栈内存空间:- 每次循环写入新输入都会覆盖上一次
temp里的内容,你直接将array[i] = temp等价于让所有数组元素都指向同一块栈地址,所以最终所有元素都显示最后一次输入的value1 - 栈局部变量的生命周期只和所属函数绑定,
create_array执行结束后,对应的栈帧会被系统回收,此时返回的array里存储的所有指针都是野指针,main函数访问这些野指针指向的内存就会触发段错误
- 每次循环写入新输入都会覆盖上一次
- 之前声明
char *temp触发段错误,是因为你没有给指针分配合法的可写内存,直接用scanf向野指针指向的地址写入内容,属于非法内存访问。
修复方案
核心逻辑是将字符串存储到堆内存中,堆内存的生命周期由开发者手动控制,不会随函数退出自动回收:
- 每次读取完
temp中的输入后,用malloc分配长度为strlen(temp)+1的堆内存(+1是为了存储字符串结束符\0) - 使用
strcpy将temp中的内容复制到新分配的堆内存中,再将array[i]指向该堆内存地址 - 程序使用完数组后,需要先逐个释放每个字符串的堆内存,再释放数组本身的内存,避免内存泄漏
修复后的完整代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> char** create_array(int num); int main(){ char** my_array; int i; printf("%s", "Input the size of the array: "); scanf("%d", &i); my_array = create_array(i); for (int m = 0; m < i; m++){ printf("%s\n", my_array[m]); } // 内存释放逻辑 for (int m = 0; m < i; m++){ free(my_array[m]); } free(my_array); return 0; } char ** create_array(int num){ char** array = malloc(num * sizeof(char*)); for (int i = 0; i < num; i++) { char temp[32]; printf("Input element %d of the array: ", i); // 限制输入长度避免栈溢出,最多读31个字符,留1位存结束符 scanf("%31s", temp); // 分配堆内存存储字符串 array[i] = malloc(strlen(temp) + 1); strcpy(array[i], temp); } for (int m = 0; m < num; m++){ printf("%s\n", array[m]); } printf("end of func\n"); return array; }
内容的提问来源于stack exchange,提问作者Julia Fasick
相关产品推荐
相关产品推荐

