为何strncpy给char*赋值会触发seg fault,改用char数组则正常?
为什么结构体中char*和char数组处理字符串的方式不同?
先明确:数组和指针根本不是一回事
很多人会被「数组名会隐式转换为指针」的特性误导,以为二者本质相同,但它们的内存模型完全不一样:
char data[512]:定义了一块固定大小的可写内存区域,数组名是这块内存的起始地址,你可以直接往里面写数据。char* data:定义了一个指针变量,它只存储一个内存地址,但本身不附带任何内存空间——如果不给它分配合法的可写内存,它要么是野指针,要么指向只读区域。
逐个分析你的三段代码情况
1. 直接给char*赋值字符串常量不崩溃
对应代码大概是这样:
struct node { char* data; }; struct node n; n.data = "hello"; // 运行正常
这里的"hello"是字符串字面量,存储在程序的只读数据段。你只是把这个只读区域的地址赋值给了data指针——整个过程没有写操作,只是读取、存储地址,所以不会触发段错误。但要注意:如果之后尝试修改data指向的内容(比如n.data[0] = 'H'),一样会崩溃,因为写了只读内存。
2. 用strncpy给char*赋值触发段错误
对应代码大概是这样:
struct node { char* data; }; struct node n; strncpy(n.data, "hello", 5); // 段错误
问题出在n.data这个指针:
- 如果没初始化,它是个野指针,指向随机的非法内存地址,strncpy往里面写数据直接触发内存访问错误。
- 如果之前赋值过字符串常量(比如
n.data = "old"),那它指向的是只读数据段,strncpy试图往只读区域写数据,同样会触发段错误。
strncpy是写内存操作,必须确保目标指针指向一块你有权限写的合法内存空间,而char*本身不提供这块空间。
3. 改成char数组后用strncpy正常
对应代码大概是这样:
struct node { char data[512]; }; struct node n; strncpy(n.data, "hello", 5); // 正常运行
这里的data[512]是结构体自带的一块可写内存(局部变量在栈上,全局变量在全局数据段),strncpy直接往这块合法的可写内存里拷贝数据,自然不会有问题。
总结
- 如果你用
char*存储字符串,必须先给它分配可写内存(比如用malloc申请堆内存,或者让它指向一块已存在的可写数组),才能用strcpy/strncpy这类写操作函数。 - 数组本身自带内存空间,不需要额外分配,直接可以用来存储字符串。
内容的提问来源于stack exchange,提问作者c questions
相关产品推荐
相关产品推荐

