繁体   English   中英

微小的崩溃程序

[英]Tiny crashing program

以下程序使用g ++编译,但是在运行时崩溃:

class someClass
{
public:
    int const mem;
    someClass(int arg):mem(arg){}
};

int main()
{
    int arg = 0;
    someClass ob(arg);

    float* sample;
    *sample = (float)1;

    return 0;
}

以下程序不会崩溃:

int main()
{

    float* sample;
    *sample = (float)1;

    return 0;
}
float* sample;
*sample = (float)1;

sample从未初始化为指向对象,因此,当您取消引用它时,程序将崩溃。 您需要先对其进行初始化,然后再使用它,例如:

float f;
float* sample = &f;
*sample = (float)1;

即使您的第二个程序没有崩溃,它仍然是错误的。 取消引用未指向有效对象的指针会导致未定义的行为。 结果可能是您的程序崩溃,内存中的某些其他数据被覆盖,您的应用程序似乎继续正常运行或任何其他结果。 您的程序今天看起来运行良好,但明天运行时崩溃。

经过一番思考,我可以肯定地告诉您为什么第二个示例没有崩溃。

执行程序时,crt(c运行时)将3个值压入堆栈:参数数量( int ),参数为char **和环境字符串也为char ** ,然后调用main

现在,当您编写main函数时,据我所知,它总是读取前两个值,并将它们传递给函数的参数(如果有)。 如果包含第3个参数,则它也会传递第3个值,否则它将保留在堆栈中。 因此,程序开始时的堆栈如下所示:

+--------+
| # args |  
+--------+    
|  args  |  
+--------+  <------ stack pointer
|  envs  |  
+--------+  

在第一个示例中,您在堆栈上分配了int和struct,然后是指针,因此第一个示例中的完整堆栈如下所示:

+--------+
| # args |  
+--------+    
|  args  |  
+--------+  <------ stack pointer
|  arg   |  <------ your integer, initialized in code
+--------+  
|   ob   |  <------ your struct, initialized in code
+--------+  
| sample |  <------ your pointer, uninitalized = garbage
+--------+  

因此, sample是纯垃圾,尝试取消引用它会使您的程序崩溃。

现在在第二个示例中,堆栈如下所示:

+--------+
| # args |  
+--------+    
|  args  |  
+--------+  <------ stack pointer
| sample |  <------ pointer, uninitalized (!)
+--------+  

指针仍然是未初始化的,但是它改写的值是envp ,它是指向数组的实际指针: char ** 取消引用它时,您将返回一个“指向char的指针”数组,因此可以安全地覆盖它(只要您不再尝试将其视为原始指针)。 内存已分配,您可以使用它。

现在,这当然是特定于实现的,但是似乎适合您的编译器,对吗? 您可以通过gdb检查(char**)sample确实指向环境变量数组,然后再覆盖它。

MSVC ++ 10中的屏幕快照,处于32位发布模式下(调试模式会强制初始化所有变量,以防止发生这种情况):

实际使用中的指针http://img651.imageshack.us/img651/5918/69916340.png

取消引用未初始化的指针: http : //www.cprogramming.com/debugging/segfaults.html

您正在取消引用统一指针。

真正有趣的是,为什么第二个示例不会对您造成崩溃,因为它具有相同的问题

顺便说一句:对我来说(gcc 4.4,amd64)都崩溃了。

如果您真的对第二个示例为何不会崩溃感到兴趣,请使用调试信息进行编译,然后在调试器中启动它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM