指针段错误vs未定义行为

pointer segfault vs undefined behavior

本文关键字:vs 未定义 错误 段错误 指针      更新时间:2023-10-16

为什么这段代码在定期运行时产生段错误,但如果我添加命令行参数或注释调用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];
}

我知道nfn函数的局部变量,但是是否有一种方法可以溢出缓冲区或输入argv[1]的东西,以使其打印n从内存中的任何地方保存的值?

如果不传递参数,则argv[1]==nullptr。那么cpy(argv[1])cpy(nullptr), cpy调用strncpy(x,nullptr,8)和segfaults

如果你注释掉了这个拷贝,那么没有段错误。

如果你传递一个参数,那么copy将不会出现分段错误。但是接下来你会遇到一个不同的问题:fn执行了p=n,但n是在堆栈上声明的,所以回到cout<<p[0]的main中,p指向对象n,而对象n已经不存在了,所以行为是未定义的。