2011-08-26 72 views
41

是不是可以在整數數組上使用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 
+1

可能更容易做到這一點:int arr [5] = {-1}; –

+24

@Tom Dignan:除了僅將第一個元素初始化爲-1,其餘所有元素初始化爲0. – tinman

回答

69

只是改變memset (arr, -1, sizeof(arr));

注意,對於其它的值大於0和-1這是行不通的,因爲memset字節值的記憶開始於由*ptr以下指示的可變塊num字節。

void * memset (void * ptr, int value, size_t num); 

而且,由於int是在超過一個字節表示,你不會得到你的數組中的整數期望值。

例外:

  • 0是因爲一個例外,如果你設置所有字節爲0,則該值將是零
  • -1是因爲另一個例外,因爲帕特里克強調-1在0xFF的中int8_t(= 255),併爲0xffffffff在int32_t

你有原因:

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.

+5

那麼,在這種特殊情況下(對於-1來說,memset實際上是可行的)。因爲int8_t中的-1是0xff,int32_t中的0xffffffff等等。 IOW:memset對0和-1工作正常,但對於其他所有情況不是很有用。 –

+0

你是對的Patrick,謝謝..我相應地改變了我的回答 –

+6

@Patrick B.:它可以在許多平臺上正常工作,但不是全部。並非所有的平臺都使用二進制補碼,並且您也可以通過使用memset來初始化一個int來觸發陷阱表示。 –

5

爲什麼劃分的?

memset(arr, -1, sizeof(arr)); 

你的版本,sizeof(arr)/sizeof(int),爲您提供了數組中元素的個數。

+3

請注意,memset()會在尋址的位置設置_bytes_的值,而不是多少「項目」。你希望將5個字節的字節值設置爲'-1'。這樣做恰好將格式值設置爲「-1」。 –

+1

@Jeff:的確,巧合,因爲-1的int通常是$ FFFFFFFF(假設32位int和2的補碼),而-1的字節是$ FF。如果他選擇-2($ FE),它將變成$ FEFEFEFE,這是一個-16843010的整數。 –

30

不要使用memset來初始化除單字節數據類型以外的任何內容。

乍一看,它可能會出現,它應該用於初始化int0-1(和在許多系統上,將工作)工作,但此時你沒有考慮到,你可能會生成陷阱的可能性表示,導致未定義的行爲,或整數表示爲not necessarily two's complement的事實。

將數組int初始化爲-1的正確方法是遍歷數組,並顯式設置每個值。

+8

我認爲這個答案應該考慮一個條款,如「如果你想寫絕對可移植的代碼**」,不要使用memset()'... **。大多數人既不寫也不打算寫便攜式代碼。當它適用於兩種架構時,大多數人稱代碼爲「便攜式」。 「正確的方式......」中的「正確」一詞也可以更改爲「便攜式」。如果您不想編寫絕對可移植的代碼,那麼它不會更正確。 –

+0

+1 // @Complicatedseebio不能同意更多,很多程序員用'正確'和'stl this'來跳下人們的喉嚨。他們經常看到具體問題需要什麼。 –

+7

@Comlicated see bio @Adam:但是,使用循環初始化一個'int'數組可以保證在所有情況下都能正常工作,而使用memset可能無法正確執行它(或者可能會出現更糟糕的情況)。如果您熟悉代碼運行的平臺,並且知道它不會導致問題,我不會說您不能使用memset。但是我不瞭解每個可能閱讀這個答案的人的平臺,所以我更喜歡安全地玩。我希望能夠平衡我在答案中使用的某些「極端」(出於理由)。 –

4

您可以通過直接初始化數組保存自己一些打字:

int arr[5] = {-1, -1, -1, -1, -1}; 

這條線比memset的短,它也適用。

+0

數組初始值設定爲+1,雖然它僅適用於少數值。 –

9

GCC提供了一個很好的數組初始化的快捷

int arr[32] = {[0 ... 10] = 3, [11 ... 31] = 4}

心靈的空間之前和之後...

1
void * memset (void * ptr, int value, size_t num); 

當應用於設置字符數組此功能以及在大多數系統上。 它將ptr指向的內存塊的第一個數字BYTES設置爲指定的值(解釋爲無符號字符)。 memset-C++ Reference 它每次運行一個字節。因此,如果您爲int值不超過0xff的第二個參數賦值,那麼它工作正常。

至於你的版本,第三個參數是數組元素的數量,所以你得到了你的輸出。 事實上,事實是,你應該分配第三個參數你想要的字節數。 所以正確的版本應該是這樣的:

memset (arr, -1, sizeof(arr)); 
相關問題