指针段错误与未定义行为
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,所以行为未定义。
为什么这段代码在 运行 时经常产生段错误,但如果我添加命令行参数或注释掉调用 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,所以行为未定义。