在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?
在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?
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_ptr
爲following:
std::unique_ptr<int[]> p(new int[100]);
我在這裏展示的方式顯然不是一個很好的解決方案,我只是想以某種獨特的方式回答問題。
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。
'[1]'意味着你正在分配一個int [100]的單元素數組,而不是一個由100個元素組成的'int'數組。所以你得到一個指向新數組中第一個'int [100]'元素的指針。 它不會以任何實際的方式,因爲兩者都會給你一個400字節的數據塊(對於一個32位的'int')而'delete []'需要能夠處理被指向的任何一個通過它的參數而不考慮類型,我期望。 – TBBle
typedef int IntArray[100];
int main()
{
IntArray* p = new IntArray[1];
delete[] p;
return 0;
}
請注意,您必須釋放如此分配的數組與delete[]
。
不完全是你所要求的,但你可以用你想要的使用模板類型扣除。
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風格的數組一個偉大的方式就派上用場了,不時..
雖然'operator new []'返回'void *',新表達式的返回類型實際上是'T *' – PeterT
您也可以用'typedef T arrType [N];替換reinterpret轉換。 ptr = new arrType [1];'這是我和Leon所使用的相同「技巧」。 – PeterT
謝謝@PeterT,我修正了關於'operator new []'的返回類型的註釋。我不確定'typedef'技巧,因爲(它很挑剔)數組分配一個由100個元素「int」數組組成的單元數組,而不是由100個元素組成的「int」數組。我不能輕易想象一個實際的用例會有所不同 - 某種'operator new []'重載可能會將大量數組重定向到不同的池中? 無論如何,我的意圖是說明一種安全的方式,使用'new T [N];'從指針的類型中提取T和N. – TBBle
在C++中你可能會做'STD: :矢量 v(100);'。 –
或'std :: array'在這種情況下。 –
C++優雅的防錯方式是避免數組,指針或'new'。 –