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

字符数组与字符指针:为何某场景可行另一场景失效?

字符指针指向字符串常量时调用strcpy失效的原因

三段代码对比

第一段代码(正常运行)

#include <stdio.h>

int main(void) {
    char* f = "test";
    printf("%s", f);//prints "test"
}

这段代码能正常打印,是因为字符指针只是读取字符串常量的内容,没有修改操作,完全合法。

第二段代码(正常运行)

#include <stdio.h>

void strcpy(char* dst, char* src) {
    int i = 0;
    do {
        *(dst + i) = *(src + i);

    } while (*(src + (i++)));
}

int main(void) {
    char first[] = "test2";
    char second[] = "test3";

    strcpy(second, first);

    printf("%s", second); //prints "test2"
}

此处second是栈上分配的字符数组,内存属于可修改区域,strcpy的写入操作合法,因此能正常覆盖内容并打印结果。

第三段代码(出现问题)

#include <stdio.h>

void strcpy(char* dst, char* src) {
    int i = 0;
    do {
        *(dst + i) = *(src + i);

    } while (*(src + (i++)));
}

int main(void) {
    char first[] = "test4";
    char *second = "test5"; //ONLY THIS LINE IS CHANGED

    strcpy(second, first);

    printf("%s", second); //PRINTS NOTHING
}

仅修改一行代码后程序就无法正常输出,核心原因如下:

问题本质

  • char *second = "test5"中,"test5"是字符串常量,它被存储在程序的只读数据段(.rodata)中,操作系统会将这块内存标记为只读属性,禁止任何写入操作。
  • 你的strcpy函数试图往second指向的只读内存地址写入数据,这触发了未定义行为。未定义行为的表现没有固定标准:可能直接崩溃,可能输出乱码,也可能像你遇到的那样无输出,甚至在某些环境下看似正常,但这种操作绝对违反了C语言的内存规则。

关键区别

char second[] = "test3"和char *second = "test5"是完全不同的两种内存分配方式:

  • 前者是在栈上创建字符数组,并用字符串常量初始化数组内容,数组本身的内存是可修改的;
  • 后者是让指针直接指向只读数据段中的字符串常量,指针指向的内存不可修改。

额外提示:按照C标准,字符串常量的类型是const char[],虽然允许用char*指向它,但这是历史兼容写法。为了避免误修改,建议用const char*来声明指向字符串常量的指针,编译器会在你试图修改时直接报错,提前发现问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 22:17:04