簡體   English   中英

C ++:sizeof用於數組長度

[英]C++: sizeof for array length

假設我有一個名為LengthOf(array)的宏:

sizeof array / sizeof array[0]

當我制作一個新的大小為23的數組時,是否應該為LengthOf取回23?

WCHAR* str = new WCHAR[23];
str[22] = '\0';
size_t len = LengthOf(str); // len == 4

為什么len == 4

更新 :我打錯了,是WCHAR* ,而不是WCHAR**

因為這里的str是指向指針的指針,而不是數組。

這是指針和數組之間的細微差別之一:在這種情況下, 指針位於堆棧上,指向已分配給其他位置(可能是堆)的23個字符的數組。

WCHAR** str = new WCHAR[23];

首先,這甚至不應該編譯-它嘗試將pointer to WCHARpointer to pointer to WCHAR分配給pointer to WCHARpointer to pointer to WCHAR 編譯器應基於此不匹配拒絕代碼。

其次, sizeof(array)/sizeof(array[0])宏的已知缺點之一是,當應用於指針而不是實際數組時,它可能並且將完全失敗。 在C ++中,您可以使用模板來獲取拒絕的代碼:

#include <iostream>

template <class T, size_t N>
size_t size(T (&x)[N]) { 
    return N;
}

int main() { 
    int a[4];
    int *b;

    b = ::new int[20];

    std::cout << size(a);      // compiles and prints '4'
//    std::cout << size(b);    // uncomment this, and the code won't compile.
    return 0;
}

正如其他人指出的那樣,如果將指針而不是實際數組傳遞給宏,則宏將無法正常工作。 不幸的是,由於大多數表達式中的指針和數組的計算結果相似,除非您使宏變得更加復雜,否則編譯器無法讓您知道存在問題。

有關類型安全的C ++版本宏(如果傳遞指針而不是數組類型,將生成錯誤),請參見:

它不能完全“解決”您的問題,但可以讓您知道您做錯了什么。

對於在C中工作並且更安全的宏(許多指針將診斷為錯誤,但不幸的是,某些指針將通過而不會出錯-包括您的指針):

當然,使用#ifdef __cplusplus您既可以在通用標頭中使用它,也可以讓編譯器為C ++構建選擇較安全的標頭,而在C ++無效時選擇與C兼容的標頭。

問題是sizeof運算符檢查其參數的大小。 您的示例代碼中傳遞的參數是WCHAR* 因此,sizeof(WCHAR *)為4。如果您有一個數組,例如WCHAR foo[23] ,並且采用sizeof(foo) ,則傳遞的類型實質上是WCHAR[23] ,並且將產生sizeof(WCHAR) * 23 實際上,在編譯類型上, WCHAR*WCHAR[23]是不同的類型,盡管您和我可以看到new WCHAR[23]的結果在功能上等效於WCHAR[23] ,但實際上,返回類型是WCHAR* ,絕對沒有尺寸信息。

作為核心,由於您的平台上的sizeof(new WCHAR[23])等於4,因此您顯然要處理的指針為4個字節的體系結構。 如果是在x64平台上構建的,則會發現sizeof(new WCHAR[23])將返回8。

你寫了:

WCHAR* str = new WCHAR[23];

如果23是一個靜態值(在程序的整個生命周期中都不是變量),則最好使用#define或const而不是僅對 23進行硬編碼

#define STR_LENGTH 23
WCHAR* str = new WCHAR[STR_LENGTH];
size_t len = (size_t) STR_LENGTH;

或C ++版本

const int STR_LENGTH = 23;
WCHAR* str = new WCHAR[STR_LENGTH];
size_t len = static_cast<size_t>(STR_LENGTH);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM