You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 04:55:16