int main()
{
int *a; // a = 0x4053c6 (a random address)
// this will cause the program to exit, and how do i know this memory can't be written ?
*a = 5;
return 0;
}
使困惑!我的意思是这个片段是否总是导致程序崩溃?有没有这种程序可以从头到尾执行的情况?
int main()
{
int *a; // a = 0x4053c6 (a random address)
// this will cause the program to exit, and how do i know this memory can't be written ?
*a = 5;
return 0;
}
使困惑!我的意思是这个片段是否总是导致程序崩溃?有没有这种程序可以从头到尾执行的情况?
代码将 Segfault / 有访问冲突,根据操作系统将其作为陷阱或信号处理。您可能能够处理它,但之后您不太可能做很多事情。(处理后通常的做法是优雅的退出)。
至于确定有一个案例,要证明它是相当困难的。您可以拥有自己的编译器,将未初始化的变量设置为堆栈上的特定地址,例如(讽刺)。
伪初始化 a 中的值的一种方法是调用函数:
void func(int k)
{
int *a;
int b = 0;
if (k == 1) {
a = &b;
}
*a = 5;
}
您可以尝试使用 func(1) 几次,然后尝试 func(2)。a 和 b有可能重用相同的堆栈区域而不会失败。但这又是一次机会。
它通常会导致崩溃,但不能保证(因为变量未初始化,它可以包含任何值,有效或无效)。您无法通过 C++ 异常捕获访问冲突,但编译器提供了扩展来执行此操作。例如,在 Visual C++ 中,您可以使用 SEH(结构化异常处理):
#include <Windows.h>
#include <iostream>
using namespace std;
int main()
{
int* p = reinterpret_cast<int*>(0x00000100);
__try
{
*p = 10;
}
__except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
cout << "Access violation" << endl;
return -1;
}
cout << *p << endl;
}