码迷,mamicode.com
首页 > 编程语言 > 详细

你的C/C++程序为什么无法运行?揭秘Segmentation fault (core dumped)(1)

时间:2015-04-29 23:28:30      阅读:309      评论:0      收藏:0      [点我收藏+]

标签:c   c++   段错误   野指针   空指针   

什么让你对C/C++如此恐惧?

C/C++语言如此的强大,让人爱不释手,但晦涩的语法和诸多的编程陷阱让人头皮发麻。

段错误

我们通常遇到的最多的错误莫过于段错误,下面是一个经典的段错误,你没遇到过?亲,那不可能~
技术分享

好吧,一般这样的错误大都由指针引起,看看我们的代码都写了些什么:

#include "stdio.h"
#include "string.h"
#include "stdlib.h"

void func1(char ** dest,char * src,int n) {
    (*dest) = (char*)malloc(sizeof(char)*n);
    strcpy(*dest,src);

}

int main(int argc,char** args) {
    char ** p = NULL;
    char str[] = "foreach_break";
    int len = sizeof(str);
    printf("%d\n",len);

    func1(p,str,len);
    printf("%s\n",*p);
    free(p);
    p = NULL;
}

这是一段有陷阱的代码,本篇将集中精力讨论段错误的问题。

我不打算告诉你如何快速定位段错误,因为那将让你远离事实的真相,如果你打算征服段错误, 从而更好的理解C/C++语言,那么你需要看下面的内容。

从一个可以运行的程序看起

这里贴出我们的一个可以运行的版本

#include "stdio.h"
#include "string.h"
#include "stdlib.h"


void func1(char ** dest,char * src,int n) {
    (*dest) = (char*)malloc(sizeof(char)*n);
    strcpy(*dest,src);

}

int main(int argc,char** args) {
    char * p = NULL;
    char str[] = "foreach_break";
    int len = sizeof(str);
    printf("%d\n",len);

    func1(&p,str,len);
    printf("%s\n",p);

    free(p);
    p = NULL;
}

它的运行结果如下:
技术分享
它为什么可以运行?
注意和错误的代码的对比,有什么不同:

错误代码:

char ** p = NULL;
func1(p,str,len);

正确代码:

char * p = NULL;
func1(&p,str,len);

这里如果你有了一定的C语言基础,你肯定会觉得

对一个char * p的指针进行&p操作会得到一个char ** p,这似乎和正确的代码没有区别!
那么为什么会一个段错误,一个是正常运行呢?

看看汇编怎么说

我们将开始对两份代码进行反汇编,并找出段错误的原因:
我们从main函数的第1行看起:

技术分享

野指针

所谓野指针,就是存放这个指针的地址是有的,但这个指针指向的地址不明确。

零指针

所谓零指针,就是这个指针指向了虚拟地址0x0。

段错误分析

你已经知道两份代码中的指针p都已经成了零指针。

参数传递

我们关注一下func1函数的开头:
技术分享

错误代码
技术分享

正确代码
技术分享

也许你已经猜到了,在错误的代码中,我们调用func1函数,对dest参数传入了一个零指针指向的地址0x0
就像这样:func1(p,str,len);

这个跟栈没有一点关系

这种错误跟栈没有一点关系。
完全是因为错误代码中的指针的指针char ** p = NULL指向了0x0,所以*p的值就是0x0,那么你传递*p就会传递0x0

这就是段错误的原因,0x0这个地址在一个称作用户进程空间的保留或未使用的空间中,而这一段空间是被保护的,你无法访问。

我们在这里也可以尝试访问0x0地址,会得到一个无法访问的提示:
技术分享

每个应用程序被启动,都会引发操作系统实例一个进程(process).
进程拥有自己的虚拟地址空间(VMA).

就此结束?

你的C/C++程序为什么无法运行?揭秘Segmentation fault (core dumped)(1)

标签:c   c++   段错误   野指针   空指针   

原文地址:http://blog.csdn.net/gsky1986/article/details/45371051

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!