2016-08-01 32 views
4

在C,我做錯誤證明的方式來將指針應用新的運營商陣列

int (*ptr)[100]; 
ptr=malloc(sizeof *ptr); // this is the easy/error proof way of doing it 

是否有這樣做的錯誤證明C++的方式與new操作

int (*ptr)[100]; 
ptr=new __what_comes_here? 
+7

在C++中你可能會做'STD: :矢量 v(100);'。 –

+2

或'std :: array '在這種情況下。 –

+5

C++優雅的防錯方式是避免數組,指針或'new'。 –

回答

3
int (*ptr)[100]; 
相同

表示ptr是一個指針,它應該包含一個由100個整數組成的數組的地址。換句話說,在技術上如果有,是這樣的:

int arr[100]; // automatic (compile time allocated) object of 100 integers 

那麼你可能要使用:

ptr = &arr; 

但這裏是不是這樣的。所以你可以用一個簡單的指針來做。如果你想要去的動態,那麼你要麼去malloc相當於:

int *p = new int[100]; // do `delete[] p` later to reclaim memory 

需要注意的是,p是一個簡單的指針,它保存了動態分配的數組的第一個整數的地址。

但更好的做法是使用標準的容器,以避免任何內存管理:

std::vector<int> v(100); 

如果100的尺寸是固定的,那麼你可以使用:

int a[100]; // C-style 

或者

std::array<int, 100> arr; // C++11 onwards 

如果您需要再new並沒有使用上述設施的豪華,但仍希望的內存自動回收再使用unique_ptrfollowing

std::unique_ptr<int[]> p(new int[100]); 
+0

他正在尋找如何*而不是必須將枚舉放在' new'語句,但是可以像指向malloc一樣從指針聲明中推導出它。 – kfsone

+2

@kfsone,您沒有任何法律責任。不需要指向數組的指針來保存'new/malloc'分配的內存。 OP可能不太清楚C++中的語法。 'int(* p)[N]'不需要保存動態分配的內存。 – iammilind

1

我在這裏展示的方式顯然不是一個很好的解決方案,我只是想以某種獨特的方式回答問題。

template<typename> 
struct deref; 

template<typename T> 
struct deref<T*> 
{ 
    typedef T type; 
}; 

int main() { 
    int (*ptr)[100]; 
    ptr = new deref<decltype(ptr)>::type[1]; 
    return 0; 
} 

我知道[1]顯然是非常可疑的,但沒有它,new的結果似乎只是衰減到int*。所以我認爲添加它只會導致「外部」陣列衰減並使內部完好無損。

此外,這意味着您需要致電delete[]清理它,而不會導致未定義的行爲。

如果你想說服自己,這實際上分配了必要的空間,它可以正確訪問它,你可以看到the output of godbolt in an example

+0

'[1]'意味着你正在分配一個int [100]的單元素數組,而不是一個由100個元素組成的'int'數組。所以你得到一個指向新數組中第一個'int [100]'元素的指針。 它不會以任何實際的方式,因爲兩者都會給你一個400字節的數據塊(對於一個32位的'int')而'delete []'需要能夠處理被指向的任何一個通過它的參數而不考慮類型,我期望。 – TBBle

0
typedef int IntArray[100]; 

int main() 
{ 
    IntArray* p = new IntArray[1]; 

    delete[] p; 
    return 0; 
} 

請注意,您必須釋放如此分配的數組與delete[]

0

不完全是你所要求的,但你可以用你想要的使用模板類型扣除。

template <typename T, std::size_t N> 
void populate_ptr(T (*&ptr)[N]) 
{ 
    // Its a shame the return value of new T[N] is T*, not T(*)[N] 
    ptr = reinterpret_cast<T(*)[N]>(new T[N]); 
} 

int (*ptr)[100]; 
populate_ptr(ptr); 
// Don't forget to delete[](ptr) later! 

不能推斷在返回值模板,這樣你就不能使用分配,而是通過按引用應該是等價的所有用例。

不,這是處理這一點,但能夠做模板類型推演對C風格的數組一個偉大的方式就派上用場了,不時..

+0

雖然'operator new []'返回'void *',新表達式的返回類型實際上是'T *' – PeterT

+0

您也可以用'typedef T arrType [N];替換reinterpret轉換。 ptr = new arrType [1];'這是我和Leon所使用的相同「技巧」。 – PeterT

+0

謝謝@PeterT,我修正了關於'operator new []'的返回類型的註釋。我不確定'typedef'技巧,因爲(它很挑剔)數組分配一個由100個元素「int」數組組成的單元數組,而不是由100個元素組成的「int」數組。我不能輕易想象一個實際的用例會有所不同 - 某種'operator new []'重載可能會將大量數組重定向到不同的池中? 無論如何,我的意圖是說明一種安全的方式,使用'new T [N];'從指針的類型中提取T和N. – TBBle