cas*_*per 3 c++ pointers char strcat
我们知道strcat()修饰了指向目标数组的指针,并将其与源字符串连接起来。目标数组应足够大以存储串联的结果。最近我发现,即使目标数组的大小不足以添加第二个字符串,对于小型程序,strcat()仍然可以按预期执行。我开始浏览stackoverflow并发现了几个 - 这个问题的答案。我想更深入地了解在下面运行此代码时硬件层中到底发生了什么?
#include<iostream>
#include<iomanip>
#include<cmath>
#include<cstring>
using namespace std;
int main(){
char p[6] = "Hello";
cout << "Length of p before = " << strlen(p) << endl;
cout << "Size of p before = " << sizeof(p) << endl;
char as[8] = "_World!";
cout << "Length of as before = " << strlen(as) << endl;
cout << "Size of as before = " << sizeof(as) << endl;
cout << strcat(p,as) << endl;
cout << "After concatenation:" << endl;
cout << "Length of p after = " << strlen(p) << endl;
cout << "Size of p after = " << sizeof(p) << endl;
cout << "Length of as after = " << strlen(as) << endl;
cout << "Size of as after = " << sizeof(as) << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
运行此代码后,数组p []的长度为12,而p []的大小为6。如何在这样的数组大小上物理存储这样的长度?我的意思是,对于此数组,字节数是有限的,所以这意味着strlen(p)函数仅查找NULL终止符,并一直计数直到找到它并忽略该数组的实际分配大小。sizeof()函数并不真正在意数组中最后一个为空字符分配的元素是否存储了空字符。
数组p是在函数堆栈框架上分配的,因此strcat缓冲区“溢出” p并继续写入堆栈的其他区域-通常,它会覆盖其他局部参数,函数返回地址等(请注意,在x86平台上,函数堆栈通常增长“向下”,即指向较小的地址)。这是众所周知的“缓冲区溢出”漏洞。
strlen不知道缓冲区的实际大小是多少,它只是寻找0-terminator。另一方面,sizeof是一个编译时函数,以字节为单位返回数组大小。