c - 当目标缓冲区小于源缓冲区时的 strcpy

标签 c string buffer-overflow strcpy

我试图了解 strcpy 和 strncpy 的区别/缺点。 有人可以帮忙吗:

void main()
{
char src[] = "this is a long string";
char dest[5];

strcpy(dest,src) ;
printf("%s \n", dest);
printf("%s \n", src);

}

输出是:

this is a long string 
a long string 

问题:我不明白,source sting 是如何被修改的。根据解释,strcpy 应该一直复制直到它遇到 '\0',它确实如此,但是为什么“src”字符串被修改了。

请解释。

最佳答案

简单的答案是,您(通过 strcpy() 调用)做了一些超出系统规范的事情,因此理所当然地遭受未定义的行为。

更困难的答案涉及检查系统上的具体内存布局,以及 strcpy() 的内部工作方式。它可能是这样的:

     N+28 "g0PP"
     N+24 "trin"
     N+20 "ng s"
     N+16 "a lo"
     N+12 " is "
src  N+08 "this"
     N+04 "DPPP"
dest N+00 "DDDD"

字母D代表dest中的字节,字母P是填充字节,0字符是ASCII NUL字符用作字符串终止符。

现在 strcpy(dest,src) 将稍微改变内存内容(假设它正确处理了重叠的内存区域):

     N+28 "g0PP"
     N+24 "trin"
     N+20 "g0 s"
     N+16 "trin"
     N+12 "ng s"
src  N+08 "a lo"
     N+04 " is "
dest N+00 "this"

即虽然 dest 现在“包含”完整的字符串“这是一个长字符串”(如果算上溢出的内存),src 现在包含一个完全不同的以 NUL 结尾的字符串“一个长字符串”。

关于c - 当目标缓冲区小于源缓冲区时的 strcpy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1601791/

相关文章:

c# - 如何在 String.Split() 方法中使用字符串作为分隔符?

c - 利用缓冲区溢出

c - 如何写入任意内存地址

c++ - EAI_NODATA 和 EAI_ADDRFAMILY 未声明(Linux 操作系统)

python - 使用 dict 翻译字符串

c - 在没有条件语句或运算符的情况下重写一段 C 代码?

javascript - 如何将函数添加到javascript中的特定字符串

sockets - 是否可以在不使用 Android SDK 管理实用程序的情况下下载 Android SDK 组件?

c - 如何使用 gcc 的 -I 命令添加递归文件夹

c++ - 在 CMake 中强制使用 C99(使用 'for' 循环初始声明)