日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > 你的C/C++程序為什么無法運行?揭秘Segmentation fault (1)

你的C/C++程序為什么無法運行?揭秘Segmentation fault (1)

來源:程序員人生   發布時間:2015-05-28 08:33:15 閱讀次數:4600次

甚么讓你對C/C++如此恐懼?

晦澀的語法?還是優秀IDE的欠缺?
我想那都不是問題,最多的多是1個類似這樣的毛病:

這里寫圖片描述

段毛病(Segmentation fault)

這是新手沒法避免的毛病,也是老手極力躲避也常常遇到的毛病。
本篇,試圖簡略地剖析1段會引發這個毛病的程序,帶來1些啟發。

先看兩份代碼,1份是毛病的.

毛病代碼

#include "string.h" #include <stdlib.h> #include <stdio.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 ",len); func1(p,str,len); printf("%s ",*p); free(p); p = NULL; }

正確代碼

#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 ",len); func1(&p,str,len); printf("%s ",p); free(p); //p = NULL; }

代碼意圖來自技術問答中的1個huffman樹不能運行的問題。
固然,我剝離掉了大部份關于huffman的部份,并略加改動。

它們最大的不同:
毛病代碼:

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

正確代碼:

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

或許你會奇怪,你看到“正確”的代碼中竟然注釋了這行:

//p = NULL;

參數傳遞

同時,可能有人會覺得指針char ** p向函數func1傳遞*p,與指針char * p向函數func1傳遞&p沒甚么不同啊?

嗯。這類想法也很有慣性,由于C語言沒有類似這樣的函數聲明:
void func(int &)

同時,對char * p&p操作不也得到個char **嗎?

運行程序

那末,我們看看程序自己怎樣說?
這里寫圖片描述

如果你常常遇到段毛病,希望你仔細看明白上面的圖在說甚么。

野指針

所謂野指針,就是很野的指針,你不知道它指向了哪一個地址,也不知道對這個地址取值是不是會出錯,但,野指針也是指針,有1個寄存它的內存地址.

正確的代碼中,寄存指針p的地址是0x7fffffffddc0;
毛病的代碼中,寄存指針p的地址是0x7fffffffdd78

零指針

所謂零指針,就是指向了0x0的指針.對這個0x0取值是不是會出錯呢?你想想.

這里寫圖片描述

懸浮指針

你對在正確的程序中注釋了p = NULL而感到不解?
其實這沒甚么,取決于這個指針p在后續代碼中怎樣使用.

free(p);

這句代碼的履行,會釋放掉指針p所指向的內存地址,歸還給操作系統.
固然條件是這個地址確有所指、你也有權訪問它.

p = NULL;

這句代碼的履行,是讓指針p指向了0x0,變回了空指針.

雖然它指向的內存已被釋放,但是它還指向那個地址.

這就是懸浮指針,指向的地址已不可用確還指向,就不是確有所指.

由于我們的main函數行將履行終了,所以在它返回后,寄存空指針p的地址會被釋放.

由于指針pmain函數的1個臨時變量.

所以我們可以毫無顧慮的注釋掉p = NULL.

內存泄漏

另外,如果free(p)沒有被履行,而先履行了p = NULL,那末p原來指向的內存空間可能就沒法被正確釋放,如果再也沒有其它的援用指向了那塊地址,那塊地址就被遺忘在那里,同時不能被回收.

這個,叫內存泄漏 (Memory Leak).

接著看程序

現在,我們來看看函數func1的調用。

首先,是C代碼:
這里寫圖片描述

然后是兩段代碼的對照:
這里寫圖片描述

你應當已看出了差別。

毛病的代碼的dest參數傳入了0x0.

接著是履行:

(*dest) = (char*)malloc(sizeof(char)*n);

這句代碼在進行(*dest)時就會產生段毛病.

究其緣由,就在于char ** p = NULLp變成了零指針,*p相當于對0x0這個地址取值.

利用程序啟動時,操作系統會建立1個進程(process),這個進程具有自己獨立的地址空間,稱作虛擬地址空間(virtual memory space).

0x0在這個空間中,不能被訪問.

試圖訪問1個不能被訪問的空間,就會段毛病.

總結

段毛病的1種,我們探索終了.
現在你知道以下兩種操作的含義了嗎?

/* p指向的地址,對其取值,如果這個地址有東西,也有權取,沒問題.*/ char ** p -> *p; (1) /* 寄存p的地址,或指向p的援用,這個地址必定有東西,所以沒問題*/ char * p -> &p (2);

本篇結束.

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 国产香蕉视频在线播放 | 玖玖玖国产精品 | www.黄在线看 | 男女免费视频 | 亚洲国产精品久久人人爱 | 午夜精品久久久久久久久 | 国产伦精品一区二区三区照片 | 日韩精品大片 | 国产精品久久久久久网站 | 国产亚洲视频在线观看 | 国产精品免费观看视频 | 精品日韩一区二区三区 | 欧美一级特黄aa大片 | 91视频国产区 | 成人一区在线视频 | 亚洲欧美日韩国产 | 亚洲国产成人91精品 | 99seav | 成人在线视频免费观看 | 久久免费福利 | 免费日韩一区二区 | 91精品国产综合久久精品图片 | 久久亚洲一区二区 | 色亚洲欧美 | 国产精品美女久久久久aⅴ国产馆 | 一级片aaaa | 欧美日韩在线电影 | 99久久精品国产一区二区三区 | 九九视频在线 | 久久成人国产精品 | 一区二区三区四区不卡视频 | av毛片一区 | 欧美性受xxx | 日韩精彩视频 | 日韩成人免费电影 | 国产精品99久久久久 | 亚洲成人麻豆 | 国产香蕉精品视频 | 天堂成人国产精品一区 | 免费在线观看av网站 | 97视频免费在线 |