是不是可以在整数数组上使用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