2013-05-30 31 views
2

的代碼顯示這些行以下錯誤:C++解除引用一個空指針,轉換INT PTR作廢的ptr

int e = 5, * ePtr = &e; 
void * vPtr = ePtr; 
cout << *vPtr; 

語法錯誤:

`void*' is not a pointer-to-object type

我知道:

  1. 任何指針類型可以存儲在void指針類型中,不需要顯式強制轉換
  2. 解引用嘗試void指針是語法錯誤

但是如果我們不能做點#2,除了語法上正確之外,點#1的用法是什麼?我想用vPtr打印5(即e)..這可能嗎?

這工作得很好:

int e = 5, * ePtr = &e; 
void * vPtr = ePtr; //specific to generic Ok! 
double * dPtr = (double *)vPtr; //to let compiler know stoarge size 
cout << *dPtr; //indirectly it is vPtr i.e. a void ptr, can be deref only if cast 
+4

'void *'幾乎專門用於存儲任何指針,因此您可以將它轉換回正確的類型並使用它。而且它更多的是C編碼風格。 – chris

+0

嘗試使用投射void * vPtr =(void *)ePtr; – ahmedsafan86

+0

@Ahmedsafan,你正在尋找反引號:'\'void * vPtr =(void *)ePtr;'' – chris

回答

4

void*可以指向任何東西,因此給予任何指針,這是完全正常的。

但由於它可能指向任何東西,提領它是不可能的:編譯器不知道哪個對象類型它指向,所以它無法生成代碼做取決於對象的類型正確的事情

2

存儲指針並保持其類型無關緊要可能很有用。這是void *的用途。在純C中設計存儲容器(鏈表,哈希映射)時,可以採用這種方法。

如果您想要使用指針,則必須跟蹤其類型及其值,因爲你不能任意指定指針,並且所有的類型信息在你投向void *時都會丟失。

在您的示例中,您可以使用帶void *和類型字段的簡單結構。

在C++中,你可以用多態結構甚至模板來實現這些事情:你所做的更多的是C風格。

1

您無法在此處使用void*打印e而沒有使用類型轉換。 指針不僅僅是一個存儲地址的簡單變量,它還有一個類型,告訴編譯器應該使用該地址讀多大。 A void*,因爲它沒有任何類型,所以不能在沒有類型轉換的情況下解除引用。通過類型轉換,您可以告訴編譯器應該從指針所攜帶的地址開始讀取多少字節。

void*爲程序員提供了一種簡單的方法來輕鬆存儲和使用其他類型的指針。由於指針的大小取決於處理器,因此我們不能使用unsigned int或類似的函數來存儲指針的值。另外,我們可以使用void*來使函數的指針參數/返回值更通用。

+0

raj raj:不是這樣,做一個「void * vPtr =(int *)ePtr; cout << * vPtr;「生成相同的錯誤。所以一旦宣佈無效類型的指針,它永遠不會被解除引用。 – ShivaniDhanked

+0

看到編輯,可能你的意思是。謝謝! – ShivaniDhanked

+0

我的意思是,在將'void *'強制轉換爲實際類型後,我們可以將'void *'解引用。 –

5

要遵循void*指針,您需要將指針轉換回兼容類型。

void*指針經常用在C中,但是,因爲在C++中我們可以做函數重載和多態,所以它們的使用更加有限。

使用的用C void*指針的良好爲例是使用回調函數:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, 
        void *(*start_routine) (void *), void *arg); 

當你調用在pthread_create函數,調用你的start_routine回。 在這種情況下,您可能需要將一些數據傳遞給您的start_routine。由於線程庫不能爲每種類型聲明一個pthread_create函數,所以您可能想傳遞給您回調函數,而是使用void*類型。

void myCallBack(void* arg) { 
    int* value = (int*)arg; 

    /* Do something with value: it is an int* now*/ 
    printf("Message from callback %d\n", *value); 
} 


/* Some main function or whatever... */ 
{ 
    /* ... */ 
    int foo = 123; 
    ret = pthread_create(&thread, &attr,myCallBack, &foo); 

    /* ... */ 
} 
3

你不能取消引用它,因爲編譯器不知道它是什麼。你必須把它轉換成適當的類型(並且編譯器必須假設你知道你在做什麼)。

void *指針最適用於與相當低級別的內容(如I/O驅動程序)進行接口的地方,在這種情況下,您幾乎不關心正在處理的數據,只知道您有一個緩衝區和一個尺寸。

任何其他用途都充滿危險。例如

int i = 5; 
void *p = &i; 
..... 
float *f = (float *)p; 

這將不會得到編譯器錯誤或警告。這是完全有效的。但它不太可能做你期望的事情

0

我的事情,所以你想存儲int指針void *指針。 在這種情況下,您可能會收到警告,如「從不同大小的整數轉換爲指針」。爲此,您首先需要分配一些與整數有關的內存空指針,然後使用該空指針可能會跟隨,

void *ptr = malloc(sizeof(int)); 
*((int*)ptr) = 5; 
printf("%d\n",*((int*)ptr));