C语言内存分配疑问:N=1时首字母缩写结果不符预期的原因
嘿,这个问题的核心是缓冲区溢出(Buffer Overflow),属于C语言里典型的未定义行为场景,咱们一步步拆解:
1. 内存分配的根本问题
你给str分配的内存只有1 * sizeof(char)(也就是1字节),但这个空间连你预期的结果"t"都存不下——因为C语言里字符串需要以'\0'作为结束标志,"t"加上终止符至少需要2字节的内存。
而你的acronyms函数逻辑是提取每个单词的首字母,完全没有检查st的可用空间:当输入"three letter acronym"时,它会依次往st里写入't'、'l'、'a',最后再加一个'\0',总共需要4字节的空间,这远远超出了你分配的1字节。
2. 为什么会输出"tla"?
C语言不会自动检查指针或数组的内存边界,当你往str指向的内存区域之外写数据时,这些数据会覆盖相邻的内存空间。在你的程序里,sen是在str之后调用malloc分配的,堆内存的分配通常是连续的,所以溢出的'l'、'a'和'\0'刚好写到了str相邻的、属于sen的内存区域(或者堆里的其他空闲内存)。
当你调用puts(acronyms(str, sen))时,puts会从str的起始地址开始读取字符,直到遇到'\0',而这些越界写入的字符刚好在连续的内存中,所以就输出了完整的"tla"。
3. 这是非常危险的未定义行为
这种情况属于C标准里的未定义行为——也就是说,编译器和运行环境没有义务保证程序的行为符合预期:这次可能输出"tla",下次可能直接崩溃,甚至可能被恶意利用。如果你想得到预期的"t",不仅要把N改成至少2(存't'和'\0'),还要修改acronyms函数,让它只写入第一个首字母就停止。
内容的提问来源于stack exchange,提问作者Shir K

