是不是可以在整數數組上使用memset?我嘗試了下面的memset調用,並沒有在int數組中得到正確的整數值。爲什麼「memset(arr,-1,sizeof(arr)/ sizeof(int))」不能將整數數組清除爲-1?
int arr[5];
memset (arr, -1, sizeof(arr)/sizeof(int));
Vaules我是:
arr[0] = -1
arr[1] = 255
arr[2] = 0
arr[3] = 0
arr[4] = 0
是不是可以在整數數組上使用memset?我嘗試了下面的memset調用,並沒有在int數組中得到正確的整數值。爲什麼「memset(arr,-1,sizeof(arr)/ sizeof(int))」不能將整數數組清除爲-1?
int arr[5];
memset (arr, -1, sizeof(arr)/sizeof(int));
Vaules我是:
arr[0] = -1
arr[1] = 255
arr[2] = 0
arr[3] = 0
arr[4] = 0
只是改變memset (arr, -1, sizeof(arr));
注意,對於其它的值大於0和-1這是行不通的,因爲套memset字節值的記憶開始於由*ptr
以下指示的可變塊num
字節。
void * memset (void * ptr, int value, size_t num);
而且,由於int
是在超過一個字節表示,你不會得到你的數組中的整數期望值。
例外:
你有原因:
arr[0] = -1
arr[1] = 255
arr[2] = 0
arr[3] = 0
arr[4] = 0
是因爲,在你的情況下,一個int的長度是4個字節(32位表示),你的數組的長度是20(= 5 * 4),你只設置5個字節爲-1 = 255)而不是20.
那麼,在這種特殊情況下(對於-1來說,memset實際上是可行的)。因爲int8_t中的-1是0xff,int32_t中的0xffffffff等等。 IOW:memset對0和-1工作正常,但對於其他所有情況不是很有用。 –
你是對的Patrick,謝謝..我相應地改變了我的回答 –
@Patrick B.:它可以在許多平臺上正常工作,但不是全部。並非所有的平臺都使用二進制補碼,並且您也可以通過使用memset來初始化一個int來觸發陷阱表示。 –
爲什麼劃分的?
memset(arr, -1, sizeof(arr));
你的版本,sizeof(arr)/sizeof(int)
,爲您提供了數組中元素的個數。
請注意,memset()會在尋址的位置設置_bytes_的值,而不是多少「項目」。你希望將5個字節的字節值設置爲'-1'。這樣做恰好將格式值設置爲「-1」。 –
@Jeff:的確,巧合,因爲-1的int通常是$ FFFFFFFF(假設32位int和2的補碼),而-1的字節是$ FF。如果他選擇-2($ FE),它將變成$ FEFEFEFE,這是一個-16843010的整數。 –
不要使用memset
來初始化除單字節數據類型以外的任何內容。
乍一看,它可能會出現,它應該用於初始化int
到0
或-1
(和在許多系統上,將工作)工作,但此時你沒有考慮到,你可能會生成陷阱的可能性表示,導致未定義的行爲,或整數表示爲not necessarily two's complement的事實。
將數組int
初始化爲-1
的正確方法是遍歷數組,並顯式設置每個值。
我認爲這個答案應該考慮一個條款,如「如果你想寫絕對可移植的代碼**」,不要使用memset()'... **。大多數人既不寫也不打算寫便攜式代碼。當它適用於兩種架構時,大多數人稱代碼爲「便攜式」。 「正確的方式......」中的「正確」一詞也可以更改爲「便攜式」。如果您不想編寫絕對可移植的代碼,那麼它不會更正確。 –
+1 // @Complicatedseebio不能同意更多,很多程序員用'正確'和'stl this'來跳下人們的喉嚨。他們經常看到具體問題需要什麼。 –
@Comlicated see bio @Adam:但是,使用循環初始化一個'int'數組可以保證在所有情況下都能正常工作,而使用memset可能無法正確執行它(或者可能會出現更糟糕的情況)。如果您熟悉代碼運行的平臺,並且知道它不會導致問題,我不會說您不能使用memset。但是我不瞭解每個可能閱讀這個答案的人的平臺,所以我更喜歡安全地玩。我希望能夠平衡我在答案中使用的某些「極端」(出於理由)。 –
您可以通過直接初始化數組保存自己一些打字:
int arr[5] = {-1, -1, -1, -1, -1};
這條線比memset的短,它也適用。
數組初始值設定爲+1,雖然它僅適用於少數值。 –
GCC提供了一個很好的數組初始化的快捷
int arr[32] = {[0 ... 10] = 3, [11 ... 31] = 4}
心靈的空間之前和之後...
void * memset (void * ptr, int value, size_t num);
當應用於設置字符數組此功能以及在大多數系統上。 它將ptr指向的內存塊的第一個數字BYTES設置爲指定的值(解釋爲無符號字符)。 memset-C++ Reference 它每次運行一個字節。因此,如果您爲int值不超過0xff的第二個參數賦值,那麼它工作正常。
至於你的版本,第三個參數是數組元素的數量,所以你得到了你的輸出。 事實上,事實是,你應該分配第三個參數你想要的字節數。 所以正確的版本應該是這樣的:
memset (arr, -1, sizeof(arr));
可能更容易做到這一點:int arr [5] = {-1}; –
@Tom Dignan:除了僅將第一個元素初始化爲-1,其餘所有元素初始化爲0. – tinman