2017-04-06 25 views
0

我遇到了一些代碼,其中聲明的同一行上使用了指針。這是它的基本SSCCE:在聲明的同一語句中使用指針

#include "stdafx.h" 
#include <iostream> 

struct C 
{ 
    uint32_t a; 
}; 

int main() { 
    C* pC = (C*) malloc(sizeof(*pC));  // <---- ??? 
    pC->a = 42; 

    std::cout << pC << std::endl; 
    std::cout << pC->a << std::endl; 

    free(pC); 
} 

當我嘗試做(在free()前插入)與uint32類似的事情:

uint32_t a = a + pC->a; 
std::cout << a << std::endl; 

然後要麼沒有打印此語句,或在調試隨機值存儲在a和VS2015給我一個運行時警告。執行後的錯誤級別是3.我知道這是行不通的。

爲什麼我可以使用指針?這是否合法?編譯器爲什麼不抱怨這樣的陳述?該聲明是否在幕後分裂爲多個聲明?

+2

未在SSCE正在使用的指針的值時,僅使用它的類型 - '的sizeof(* PC) '和sizeof(C)'是一樣的。使用某些* value *和使用它的* type *是非常不同的。 –

+1

'malloc'和'free'?正在編程C或C++? – JHBonarius

+0

C++。正如我所說的,這不是我自己的代碼,我只是將它剝離到了獲得SSCCE的基本部分。我知道我應該使用新的/刪除。另外,downvoter可以解釋爲什麼這不是一個好問題? – Timmos

回答

3

uint32_t a = a + pC->a;因爲你使用的a之前它被初始化這是不確定的行爲給你不好的結果。欲瞭解更多關於此看到Why is 'int i = i;' legal?

,另一方面C* pC = (C*) malloc(sizeof(*pC));沒有使用值在初始化pCsizeof應用於命名變量時,會爲您提供其類型的大小。這是一個未評估的操作數,這意味着它不被評估。所以我們沒有使用*pC的值,而是我們得到指針指向的大小是C

您希望這樣做的一個原因是如果您更改了pC的類型,則不必更改sizeof部件。如果你有

C* pC = (C*) malloc(sizeof(C)); 

然後,你需要記住改變pC類型時改變sizeof(C)一部分。


所有的這當然可以使用避免std::unique_ptr

auto pC = std::make_unique<C>(); 
         ^here is the only place you have to specify the type 
+0

一個很好的用例非常簡潔但有用的答案。多態性對於''pC'優於'C'還是一個很好的用例? – Timmos

+0

@Timmos可能沒有,因爲你通常有一個基類指針和取消引用,只是給你基礎,即你想創建的派生類型。 – NathanOliver

+0

我剛剛發現sizeof是一個編譯時操作符,所以沒有,多態性不會工作,因爲編譯器只能看到基類型。 – Timmos