指针段错误与未定义行为

pointer segfault vs undefined behavior

为什么这段代码在 运行 时经常产生段错误,但如果我添加命令行参数或注释掉调用 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 在内存中 is/was 的任何位置保存的值?

如果您不传递参数,则 argv[1]==nullptr。然后 cpy(argv[1])cpy(nullptr) 并且 cpy 调用 strncpy(x,nullptr,8) 和段错误。

如果你注释掉 cpy,那么就没有段错误。

如果你传递一个参数,那么 cpy 就不会出现段错误。但是你会遇到一个不同的问题:fn 做了 p=n 但 n 被声明在堆栈上,所以回到 main 的 cout<<p[0],p 指向不再存在的对象 n,所以行为未定义。