C语言调用外部函数时执行strcpy触发Segment Fault问题求助
段错误原因及修复方案
核心问题
你代码中的段错误完全来自sponsor_generator函数:
char *sponsor_generator(char *country) { char sp[20]; // 局部栈数组 // ... 字符串反转逻辑 return sp; // 返回局部数组指针 }
sp是函数内的局部变量,存储在栈内存中。当函数执行完毕后,对应的栈帧会被销毁,这块内存会被系统回收或后续操作覆盖。此时返回的指针是野指针,指向的内存已经无效。后续strcpy尝试从这块无效内存读取数据,直接触发段错误。
修复方案
方案一:直接操作目标缓冲区(最适合你的代码结构)
修改sponsor_generator,让它直接把反转后的字符串写入传入的目标数组,不需要返回指针:
void sponsor_generator(char *country, char *dest) { int len = strlen(country); int k = 0; for (int i = len - 1; i >= 0; i--) { dest[k++] = country[i]; } dest[k] = '\0'; // 手动添加字符串终止符 }
然后在read函数中调用时,直接传入结构体里的sponsor数组:
sponsor_generator((ec + *n)->country, (ec + *n)->sponsor);
这种方式完全避免了野指针问题,也不需要额外的内存分配,效率更高。
方案二:动态分配内存(需注意内存释放)
如果一定要返回指针,可以使用malloc在堆上分配内存(堆内存不会随函数结束而销毁):
char *sponsor_generator(char *country) { int len = strlen(country); char *sp = malloc(len + 1); // 分配足够存储字符串+终止符的空间 if (!sp) { // 必须检查内存分配是否成功 perror("malloc failed"); exit(EXIT_FAILURE); } int k = 0; for (int i = len - 1; i >= 0; i--) { sp[k++] = country[i]; } sp[k] = '\0'; return sp; }
但注意:原代码中结构体的sponsor是固定大小的数组,不能直接将返回的指针赋值给它。如果用这个方案,需要修改结构体定义,把sponsor改为char *类型,并且在后续不再使用时用free释放内存,避免内存泄漏。
额外优化建议
原代码中scanf("%s", (ec + *n)->country)存在缓冲区溢出风险,如果输入的国家名称超过19个字符(因为数组大小是20,留一个位置存终止符),会导致内存越界。建议限制输入长度:
scanf("%19s", (ec + *n)->country);
内容的提问来源于stack exchange,提问作者Hiroi
相关产品推荐
相关产品推荐

