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

为何C语言中动态分配char数组使用strcat会触发段错误?

动态分配char数组与栈char数组使用strcat的行为差异及段错误原因

错误代码的核心问题

你的第一段代码触发段错误,根本原因不是缺少终止空字符,而是指针指向了只读的字符串常量区,且丢失了动态分配的堆内存:

  1. 执行char *destination = malloc(30 * sizeof(char));时,destination确实指向了堆上一块30字节的可写内存。
  2. 但紧接着destination = "Hello, ";这行代码,直接把destination的指针值替换成了字符串字面量"Hello, "在字符串常量区的地址——原来malloc分配的堆内存从此无法访问,造成内存泄漏。
  3. 同理,source = "world!"也让source指向了字符串常量区的只读内存。
  4. strcat(destination, source)试图往只读的字符串常量内存中写入拼接后的内容,而操作系统会保护只读内存不被修改,因此直接触发段错误。

正确代码的工作逻辑

第二段代码能正常运行,是因为栈数组的初始化逻辑完全不同:

  • char destination[30] = "Hello, ";是在栈上分配了30字节的可写数组内存,并把字符串字面量"Hello, "的内容(包括自带的终止\0)拷贝到了这块数组内存中。
  • strcat(destination, source)是往栈上的可写内存里追加内容,拼接后的总长度("Hello, world!"共13字节)远小于数组的30字节容量,因此不会越界,也没有权限问题。

你的核心误区

你混淆了指针赋值和字符串拷贝:

  • 给char*类型的指针直接赋值字符串字面量(destination = "Hello, ";),不是把字符串内容复制到指针原本指向的内存,而是直接改变指针的指向,让它指向只读的字符串常量区。
  • 栈数组的初始化(char arr[N] = "str";)则是把字符串内容拷贝到数组的可写内存中,这才是真正的"把字符串放到数组里"的操作。

正确使用动态内存的写法

如果要基于动态分配的内存实现字符串拼接,需要用strcpy/strncpy把字符串内容拷贝到堆内存中,而不是直接赋值指针:

char *destination = malloc(30 * sizeof(char));
strcpy(destination, "Hello, "); // 将字符串拷贝到堆内存
char *source = malloc(30 * sizeof(char));
strcpy(source, "world!");
strcat(destination, source);

// 使用完记得释放内存,避免泄漏
free(destination);
free(source);

内容的提问来源于stack exchange,提问作者Lemury

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 02:04:54