0 == nullptr == NULL

nullptr代表沒有指向任何位址

如果對沒有指向任何位址的指標,也就是指標 = nullptr,對這個指標使用*取值運算子,試圖取出位址中的內容,編譯可以通過,但執行時將會出現錯誤。

1
2
3
4
5
6
7
8
9
10
#include <iostream>
using namespace std;
void func1(int* param1) {
  cout << "param1=" << *param1 << endl;
}
int main() {
  int* p = nullptr;
  func1(p);
  return 0;
}

第7行,宣告指標p,沒有指向任何位址。

第8行,將指標p傳入函式。

第4行,將指標p使用*取值運算子試圖取出位址中的內容,但由於指標沒有指向任何位址,執行時會產生錯誤。

檢查nullptr

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
using namespace std;
void func1(int* param1) {
  if(param1 == nullptr) return;
  cout << "param1=" << *param1 << endl;
}
int main() {
  int* p = nullptr;
  func1(p);
  return 0;
}

第4行,判斷指標是不是沒有指向任何位址,若沒有指向任何位址,函式直接返回,不再往下執行。

delete nullptr

delete nullptr 不會有編譯錯誤與執行錯誤,以下程式不會有任何錯誤。

1
2
3
4
5
int main() {
  int* p = nullptr;
  delete p;
  return 0;
}

NULL

在c的標準函式庫中stddef.h定義了常數NULL就是0與nullptr。

1
2
3
#define NULL 0
//since C++11
#define NULL nullptr

第1行定義常數NULL的值為0,代表沒有指向任何記憶空間

第3行,c++11以後,定義常數NULL為nullptr,代表沒有指向任何記憶空間

0

0,代表沒有指向任何記憶空間

以下為同名函式,但參數不同,一個為int資料型態,一個為int指標,呼叫函式(0),呼叫的是參數為整數資料型態的函式。

1
2
3
4
5
6
7
8
9
10
void func3(int n) {
  printf("n = %d\n",n);//印出值
}
void func3(int* p) {
  printf("位址 = %#x\n",p);//印出位址
}
int main() {
  func3(0);
  return 0;
}
執行結果
n = 0

轉型

把指標參數設為NULL,呼叫參數為指標的函式,以下這樣寫會出錯。

1
func3(NULL);//指標參數設為NULL

因為編譯不知道你的NULL是整數指標資料型態的NULL,轉型就可以編譯成功,以下三行都可以。

1
2
3
func3(nullptr);
func3((int *)nullptr);
func3(static_cast<int *>(nullptr));

第1行,nullptr代表所有資料型態的NULL。

第2行,轉型int指標。

第3行,使用static_cast轉型成int指標,與上一行意思相同。

完整程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
void func3(int n) {
  printf("n = %d\n",n);//印出值
}
void func3(int* p) {
  printf("位址 = %#x\n",p);//印出位址
}
int main() {
  func3(0);
  func3((int *)NULL);
  func3(static_cast<int *>(NULL));
  func3(nullptr);
  return 0;
}
執行結果
n = 0
位址 = 0
位址 = 0
位址 = 0

nullptr位址為0

以下程式碼印出nullptr指標的位址,會印出0。

1
2
3
4
5
6
int main() {
  int* p = nullptr;
  cout << p << endl;
  delete p;
  return 0;
}
執行結果
0x0

nullptr記憶體位址

0x00000000-0x0000FFFF記憶體位址區間是放置nullptr指標,無法讀取這段記憶體位址區間。

原文

Each process’ virtual address space is split into partitions. On x86 32-Bit Windows, the partition of 0x00000000 - 0x0000FFFF (inclusive) is called NULL-Pointer Assignment Partition. This partition is set aside to help programmers catch NULL-pointer assignments. If a thread in your aprocess attempts to read from or write to a memory address in this partition, an access violoation is raised.

容易混淆寫法

1
2
3
4
  int a = 0 ;
  int * p1 = 0 ; //right
  int * p2 = NULL ; //right
  int * p3 = a;//error

第1行定義整數資料型態的a變數,值為0

第2行定義p1指標沒有指向任何記憶體空間

第3行定義p2指標沒有指向任何記憶體空間

第4行錯誤,指標是存放位址,而不是值,不能把整數值0放進指標

results matching ""

    No results matching ""