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

为何这段C代码未触发段错误?printf无终止符却正常输出?

#include <stdio.h>

void print(char* c) {
    printf("%s\n", c); //Uses %s to print a string
}

int main() {
    char a = 'd';
    print(&a);
    return 0;
}

问题

上述C代码中,char变量a无空终止符,将其地址传入使用printf("%s")的print函数后,未触发段错误,且仅输出'd'就停止。请问:为何这段代码未触发段错误?GCC是否将其转换为字符串字面量?无空终止符时printf如何停止输出?这属于正常行为吗?


解答
  • 为何未触发段错误?
    段错误只会在程序访问无权访问的内存区域时触发。这里printf从&a的地址开始读取字节,刚好在a的下一个内存位置读到了值为0的字节(空终止符),没有越界到非法内存范围,所以没触发段错误。这完全是巧合——取决于a在栈上的布局,以及后续内存的内容。如果a后面的内存不是0,printf会一直读取垃圾数据,直到碰到0或者访问到非法内存才崩溃。

  • GCC是否将其转换为字符串字面量?
    没有。char a = 'd';是在栈上分配的单个局部字符变量,和存储在只读数据段的字符串字面量完全是两回事。查看汇编代码就能验证:a存储在当前函数的栈帧中,传递给print的是栈内存地址,和数据段无关。

  • 无空终止符时printf如何停止输出?
    printf("%s")的逻辑是从传入的地址开始逐个读取字节,直到碰到值为\0(ASCII码0)的字节才停止。你的代码里刚好a后面的内存字节是0,所以只输出了'd'就停止。如果后续内存不是0,它会持续输出内存中的垃圾数据,直到遇到\0或者触发内存访问错误。

  • 这属于正常行为吗?
    这不是定义良好的正常行为,而是未定义行为。C标准明确要求,使用%s格式符时,传入的指针必须指向以空字符终止的字符串。你的代码违反了这个规则,程序的行为完全不可预测——这次碰巧输出'd'就停,下次可能输出乱码,甚至直接崩溃。编译器和运行环境没有义务为这种情况提供稳定的结果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 18:55:30