指標值為空作為函式引數傳入
下面以一個例子來引出這種錯誤:
#include <iostream> using namespace std; #include <stdlib.h> #include <string.h> void func(int *p) { p = (int *)malloc(sizeof(int) * 10); memset(p, 0, sizeof(p)); p[0] = 1; } int main() { int *p = NULL; func(p); cout << p[0] << endl; return 0; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
一個很簡單的函式,就是給*p
在函式中分配空間並將p[0]
置成1,最後列印輸出p[0]
。但是執行的結果卻是segmengt fault
。
我們通過檢視這段程式的彙編程式碼來分析一下出現段錯誤的原因。
Dump of assembler code for function func(int*):
0x00000000004008cd <+0>: push %rbp
0x00000000004008ce <+1>: mov %rsp,%rbp
0x00000000004008d1 <+4>: sub $0x20,%rsp
0x00000000004008d5 <+8>: mov %rdi,-0x18(%rbp)
0x00000000004008d9 <+12>: mov $0x28,%eax
0x00000000004008de <+17>: mov %rax,%rdi
0x00000000004008e1 <+20>: callq 0x400780 < [email protected]>
0x00000000004008e6 <+25>: mov %rax,-0x8(%rbp)
0x00000000004008ea <+29>: mov -0x8(%rbp),%rax
0x00000000004008ee <+33>: mov $0x8,%edx
0x00000000004008f3 <+38>: mov $0x0,%esi
0x00000000004008f8 <+43>: mov %rax,%rdi
0x00000000004008fb <+46>: callq 0x400750 <[email protected] >
0x0000000000400900 <+51>: mov -0x8(%rbp),%rax
0x0000000000400904 <+55>: movl $0x1,(%rax)
0x000000000040090a <+61>: leaveq
0x000000000040090b <+62>: retq
End of assembler dump.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
重點放在
sub $0x20,%rbp
mov %rdi,-0x18(%rbp)
- 1
- 2
- 3
這兩句彙編程式碼上。
sub $0x20,%rbp
的意思是給棧分配0x20
大小的空間。
而mov %rdi,-0x18(%rbp)
的意思是把函式的第一個引數的值壓入棧中儲存。
這說明了什麼?說明了函式中的*p
其實是一個臨時變數,和主函式並不是同一個*p
了。給臨時變數申請記憶體並賦值當前不能反映到主函式的*p
上,所以主函式的*p
還是個空指標,而列印空指標當然就段錯誤了。
下面介紹兩種解決方法:
1.函式返回臨時指標的地址:
#include <iostream>
using namespace std;
#include <stdlib.h>
#include <string.h>
int* func(int *p)
{
//此時的p是個臨時指標
p = (int *)malloc(sizeof(int) * 10);
memset(p, 0, sizeof(p));
p[0] = 1;
return p; //返回地址
}
int main()
{
int *p = NULL;
p = func(p);
cout << p[0] << endl;
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
2.傳入指向指標的指標:
#include <iostream>
using namespace std;
#include <stdlib.h>
#include <string.h>
//*p儲存的是main函式*ptr的地址
void func(int **p)
{
*p = (int *)malloc(sizeof(int) * 10);
memset(*p, 0, sizeof(*p));
*p[0] = 1;
}
int main()
{
int *ptr = NULL;
func(&ptr);
cout << ptr[0] << endl;
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
相關推薦
指標值為空作為函式引數傳入
下面以一個例子來引出這種錯誤:#include <iostream> using namespace std; #include <stdlib.h> #include <string.h> void func(int *p) { p = (int *)malloc
把tuple或者list裡的元素作為函式引數傳入
1、tuple或list中的所有元素傳入一個函式的引數列表中: 需求函式如下: tuple = (1, "foo", "bar") def myfun(number, str1, str2): return (number * 2, str1 + str2, str2 + st
java 11:陣列作為函式引數,陣列做為函式返回值
1 陣列作為引數 我們可以將陣列作為引數,傳入到函式中,其實就像我們main函式中 public void main(String [] args){};就是用陣列作為函式引數; 又如, publicclass ArrayPar { publicstaticvoid
指標和引用 作為函式引數
*和& * * 有兩個作用,一個是作為識別符號來表示這是一個指標(宣告變數時的等號左邊),也就是說存放的是地址,另外一個是作為運算子來取值(賦值等號左邊)。 int *p=NULL; int a = 1; p = &a; cout<<p<<
二維陣列作為函式引數
https://www.cnblogs.com/alantu2018/p/8465894.html 1、二維陣列的概念 在C語言中,二維陣列實際上是一種特殊的一維陣列,它的每個元素也是一個一維陣列。因此,二維陣列下標形式正確寫法如下:int arrays[i][j]。陣
C++ 之std::function() 作為函式引數入口 詳解
1. 關於std::function() 在C語言的時代,我們可以使用函式指標來吧一個函式作為引數傳遞,這樣我們就可以實現回撥函式的機制。到了C++11以後在標準庫裡引入了std::function模板類,這個模板概括了函式指標的概念 函式指標只能指向一個函式,而std::function物件可
普通值、指標、引用作為函式引數時的理解
很多時候,我們都會看到在教科書上寫著各種值傳遞,引用傳遞,一看一大堆,有時候看的還容易迷糊,什麼情況該怎麼傳總是區分不清,下邊我們用一小版塊並結合程式碼例項講解下。 一、值傳遞 // 普通值傳遞 void test(int num) {
C語言指標作為函式引數傳遞學習(一)
1. 一維指標做函式引數 傳入的指標為NULL 比如下面的例子,很多人都會理解錯: #include <stdio.h> void test(char *string) { string = "hello world"; } int main() { cha
結構體陣列作為函式引數
把結構體陣列名作為函式的一個引數,然後在這個函式的函式裡面繼續作為引數,把一個值賦給這個結構體陣列的一個變數,我再賦值的地方是有值的,在函式裡面也是有值的,但是出了這個函式回到主函式時,這個結構體陣列的變數的值就為空了。為什麼呢?因為我在使用這個函式是這樣的, iRetur
指標作為函式引數 進行記憶體釋放 並置NULL
author:張繼飛 寫在前面,前面寫了程式碼封裝free函式,但是呼叫封裝並退出後,指標並不為NULL,導致接下來以此作為判斷條件的時候就出現問題了。先前封裝函式為void _free_p_(void *ptr),通過分析,指標作為函式引數傳遞時只是傳遞了指標所指向的地址,將其賦給一個
有關 陣列作為函式引數 & 區域性變數和全域性變數及其應用
一、陣列blabla 1.0陣列元素作函式實參。 (1).陣列元素可以用作函式實參,但不能是形參。(給陣列分配的儲存單元是連續的) 2.0一維陣列名作函式引數。 (1)陣列元素作實參時,向形參變數傳遞的時陣列元素的值。 陣列名作實參時,向形參傳遞的時陣列首元素的地址。
C++(筆記)容器(vector)作為函式引數如何傳參
一、大致以下型別 void 函式名( vector< int> obj ); void 函式名( vector< int>* pobj ); void
c++中類物件直接作為函式引數所引起的問題。
這兩天在寫一個視訊轉換的程式,將H263/264編碼的視訊封裝成mov格式,用c++實現。 Wiki上說Apple的mov格式是典型的over engineering,設計的非常複雜,各種資訊使用atom原子封裝,一個atom裡面遞迴地巢狀著另外一個atom,atom的種類
函式指標作為函式引數及函式作為函式引數
轉載於:http://blog.csdn.net/vlily/article/details/7244682 轉載於:http://blog.csdn.net/shengnan_wu/article/details/8116935 轉載於:http://blog.csdn.net/callm
C語言經典例題--結構體指標變數作為函式引數的傳遞
#include <stdio.h> #include <string.h> struct student { int age; char sex; char name[30]; }; void inputstudent(struct stu
C++多維陣列:儲存方式、訪問方式和作為函式引數
C++中陣列可以巢狀,就是多維陣列。 多維陣列儲存與訪問方式 二維陣列:一維陣列可對應數學中的向量,而二維陣列可對應矩陣,可用一個二維陣列儲存矩陣。 圖1 二維陣列mat示意圖 二維陣列的橫向稱為行,縱向稱為列,上面這個陣列為三行六列。定義二維陣列的通用格式為:
c++之指標作為函式引數傳遞的問題
轉自:http://blog.csdn.net/fjb2080/article/details/5623427 原創文章,轉載請註明出處,謝謝! 作者:清林,部落格名:飛空靜渡 部落格地址:http://blog.csdn.net/fjb2080 &n
指標作為函式引數傳遞 (轉載)
這幾天在學習C過程中,在使用指標作為函式引數傳遞的時候出現了問題,根本不知道從何得解:原始碼如下: createNode(BinNode *tree,char *p) { tree = (BinNode *) malloc(sizeof(BinNo
C++用指向函式的指標作為函式引數
示例: #include <iostream> using namespace std; int add(int x, int y){ return x + y; } int sub(int x, int y){ return x - y; } int opera
C++引用作為函式引數
一. 值傳遞1. 利用值傳遞方式,實際上是把實參的內容複製到形參中,實參和形參是存放在兩個不同的記憶體空間中。在函式體內對形參的一切修改對實參都沒有影響2. 如果形參是類的物件,利用值傳遞的話每次都要呼叫類的建構函式構造物件,效率比較低二. 指標傳遞(地址傳遞)1. 當進行指標傳遞的時候,形參是指標變數,實參