为什么这段代码在定期运行时会产生段错误,但如果我添加命令行参数或注释掉调用cpy
函数,则会产生未定义的行为而不是段错误?
#include <cstdlib>
#include <iostream>
#include <cstring>
using namespace std;
int *p;
void fn() {
int n[1];
n[0]=99;
p = n;
}
void cpy(char *v) {
char x[8];
strncpy(x,v,8);
}
int main(int argc, char** argv) {
fn();
cpy(argv[1]);
cout << "p[0]:" << p[0];
}
我知道n
是函数fn
的局部变量,但有一种方法可以溢出缓冲区或输入argv[1]
之类的东西来让它打印出值n
被保留在记忆中的任何地方?
答案 0 :(得分:2)
如果你没有传递参数,那么argv[1]==nullptr
。然后cpy(argv[1])
为cpy(nullptr)
,cpy调用strncpy(x,nullptr,8)
和段错误。
如果您注释掉cpy,则不会出现段错误。
如果传递参数,则cpy不会发生段错误。但是你得到了一个不同的问题:fn做了p=n
但是n在堆栈上被声明了,所以回到主要的cout<<p[0]
,p指向不再存在的对象n,所以行为未定义。