2016-03-07 109 views
2

對於這個問題的愚蠢,我很抱歉。但是我找不到理解這個結果的方式。我試圖弄清楚C++中的指針究竟是什麼。以下是以不同方式打印地址的簡單代碼。C++中的指針地址

int a = 15000; 
char *b = reinterpret_cast<char*>(a); //equivalent of char *b = (char *)a 
int *m = &a; 

//(1) 
printf("&a:%p\n",&a);   //0x7fff5fbff878 
printf("&*m:%p\n",&*m);   //0x7fff5fbff878 
printf("m:%p\n",m);    //0x7fff5fbff878 

//(2) 
printf("a:%p\n",(int*)a);  //0x3a98 
printf("&*b:%p\n",&*b);   //0x3a98 
printf("b:%p\n",b);    //0x3a98 
printf("*m:%p\n",(int*)*m);  //0x3a98 

printf("&b:%p\n",&b);   //0x7fff5fbff870 

printf("&m:%p\n",&m);   //0x7fff5fbff868 

//(3) 
std::cout << "b:" << b << std::endl; //error: Segmentation fault: 11 

所以,問題是

  • 爲什麼的地址(1)和(2)是不同的
  • 爲什麼的(1)和(2)是大小(地址的長度)不同
  • 當一個int被強制轉換爲一個char *
  • 如何 'b' 可能含有 'A'
  • 爲什麼錯誤(3)已同時「發生的printf地址(「b發生了什麼事:%p \ n 「,b)」正在工作。
+5

提示:0x3a98 == 15000 – Michael

+0

接受道歉。如果(2)int被轉換爲指針。這是合法的,但不保證在任意的情況下有意義。在(3)的情況下,你嘗試使用這個假指針,就好像它指向了字符數組(C字符串) - 但它沒有。 – ddbug

+0

該死的,非常感謝不要指責:P –

回答

3

爲什麼的地址(1)和(2)是不同的

由於在第一實施例(1),可以使用&地址操作的,它給你的地址,其中存儲「a」變量,例如0x50302040

但是第二個例子(2),您使用的是地址(0x50302040)指向的值,該值返回15000,該值等於十六進制的0x3a98。

當一個int被強制轉換爲一個char *

如果int有15000的數值,現在char*指向地址15000,這顯然是錯誤的事了。

爲什麼在'printf(「b:%p \ n」,b)'正在工作時發生錯誤(3)。

因爲你的指針是一個char*指針,因此超載(ostream& operator<< (ostream& os, const char* s);被使用,因爲你的指針不指向一個字符序列(事實上,它並不指向,因爲你任何東西字符序列分配一個無效的值),你的程序崩潰。

即使世界一個ostream& operator<< (void* val);超載,將只打印指針的地址,但你需要你的char*指針明確地轉換爲void*指針使用它:

std::cout << "b:" << (void*)b << std::endl; // Prints 0x3a98 (15000)