字符指针数组左移遇Segmentation fault:问题排查与需求实现
问题分析与解决方案
核心错误点
- 字符串常量不可修改:
data数组的元素是指向字符串常量的指针,这些常量存储在程序的只读内存段中。strcpy(data[k], data[k+1])试图往只读内存写入数据,直接触发段错误。第一次循环没崩溃只是偶然,本质上已经是非法操作。 str未重置且越界:全局变量str初始值全为0,第一次strcat能正常拼接,但拼接后str被填满(5个7字符字符串共35字节,刚好是str的大小),没有空间存储字符串结束符'\0'。后续循环再调用strcat会越界访问内存,加剧错误。
实现数组左移的正确写法
如果只是要实现数组左移(把第一个元素移到末尾),不需要修改字符串内容,直接移动指针即可:
#include <stdio.h> int arr_size = 5; char* data[] = {"1234567", "1234576", "1234756", "1234765", "1234675"}; int main() { // 保存第一个元素的指针 char* temp = data[0]; // 左移所有元素 for (int k = 0; k < arr_size - 1; k++) { data[k] = data[k + 1]; } // 把第一个元素放到末尾 data[arr_size - 1] = temp; // 验证结果 for (int i = 0; i < arr_size; i++) { printf("%s\n", data[i]); } return 0; }
如果确实需要修改字符串内容(比如后续要修改字符串本身),需要把data定义为字符数组的数组,让每个元素都有可写的内存空间:
#include <stdio.h> #include <string.h> #include <string.h> int arr_size = 5; // 每个元素是可写的字符数组,长度8(7个字符+1个结束符) char data[][8] = {"1234567", "1234576", "1234756", "1234765", "1234675"}; char temp[8]; int main() { char str[35] = {0}; // 初始化str,确保有结束符 // 每次循环前重置str,避免拼接混乱 for (int i = 0; i < arr_size; i++) { memset(str, 0, sizeof(str)); for (int j = 0; j < arr_size; j++) { strcat(str, data[j]); } printf("拼接结果:%s\n", str); // 左移数组元素 strcpy(temp, data[0]); for (int k = 0; k < arr_size - 1; k++) { strcpy(data[k], data[k + 1]); } strcpy(data[arr_size - 1], temp); } return 0; }
额外注意事项
- 全局变量尽量少用,改用局部变量更安全。
void main()不是标准写法,标准C中应使用int main()并返回0。- 使用
strcat前,必须确保目标字符串有足够空间且以'\0'结尾,避免内存越界。
内容的提问来源于stack exchange,提问作者Torokh
相关产品推荐
相关产品推荐

