C语言代码段错误排查:用户输入存储至双数组问题
问题分析与修复方案
嘿,你的代码触发段错误(segmentation fault)的原因其实很典型,主要有两个核心问题:
- 指针数组未分配有效内存:
char *street[10]是一个装了10个字符指针的数组,但每个指针都是未初始化的「野指针」,指向的内存地址完全随机。scanf尝试往这些随机地址写数据,直接触发了非法内存访问,这就是段错误的根源。 - 门牌号的数组类型错误:门牌号是整数类型,根本不需要用
int *number[10]这种指针数组——普通的整数数组int number[10]就足够了,用指针数组同样会因为未初始化指针导致内存问题。
修复后的代码
这里给你两种实用的修复方案,你可以根据需求选择:
方案1:固定大小字符数组(简单省心)
这种方案适合你能预估街道名称最大长度的场景,代码简单直接:
#include <stdio.h> // 定义街道名称的最大长度,你可以根据实际需求调整 #define MAX_STREET_LEN 50 int main (void){ // 二维字符数组:10个元素,每个元素是能存50个字符的数组 char street[10][MAX_STREET_LEN]; // 普通整数数组存门牌号 int number[10]; int i; for (i=0;i<10;i++){ printf("Enter street and number: \n"); // 注意:%s会自动在字符串末尾加结束符'\0',所以实际最多存MAX_STREET_LEN-1个字符 scanf(" %s %d", street[i], &number[i]); } // 验证街道数组的存储结果 printf("Stored street names:\n"); for (int i=0;i<10;i++){ printf("%s ", street[i]); } printf("\n"); // 顺便验证门牌号(可选) printf("Stored house numbers:\n"); for (int i=0;i<10;i++){ printf("%d ", number[i]); } printf("\n"); return 0; }
方案2:动态分配内存(灵活适配任意长度)
如果不确定街道名称的长度,用动态分配内存更合适,能避免浪费空间:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main (void){ char *street[10]; int number[10]; int i; // 临时缓冲区先存输入的街道名称 char temp[100]; for (i=0;i<10;i++){ printf("Enter street and number: \n"); // 先把街道名读到临时缓冲区 scanf(" %s %d", temp, &number[i]); // 根据输入的实际长度分配内存(+1是给结束符'\0'留位置) street[i] = malloc(strlen(temp) + 1); // 一定要检查内存分配是否成功,避免后续出错 if (street[i] == NULL) { printf("Oops, memory allocation failed!\n"); return 1; } // 把临时缓冲区的内容复制到分配好的内存里 strcpy(street[i], temp); } // 验证存储结果,同时记得释放内存(避免内存泄漏) printf("Stored street names:\n"); for (int i=0;i<10;i++){ printf("%s ", street[i]); free(street[i]); } printf("\n"); return 0; }
小提醒
- 字符指针
char *本身不存字符串,它只是个「指向字符串的地址」,使用前必须确保它指向有效的、已分配的内存——要么是固定大小的数组,要么是用malloc动态分配的内存。 - 用
scanf读整数时,要传变量的地址(比如&number[i]),因为scanf需要通过地址修改变量的值。
内容的提问来源于stack exchange,提问作者user9741196
相关产品推荐
相关产品推荐

