char str[] = "beautiful earth";
memset(str, '*', 6);
printf("%s", str);
Output:
******ful earth
像上面使用memset一样,我们能否只将几个整数数组索引值初始化为1,如下所示?
int arr[15];
memset(arr, 1, 6);
不,你不能像这样使用memset()
函数。该手册页中指出(重点是我的):
memset()
函数将由s
指向的内存区域的前n
字节用常数c
填充。
由于一个int
通常是4个字节,因此这种用法行不通。
如果您(错误地!)尝试这样做:
int arr[15];
memset(arr, 1, 6*sizeof(int)); //wrong!
如果数组的前6个int
实际上被设置为0x01010101 = 16843009,则可以使用该语句。
唯一真正可接受的用非字节数据类型覆盖“blob”数据的情况是使用memset(thing, 0, sizeof(thing));
函数来将整个结构/数组“清零”。这能够奏效是因为NULL、0x00000000、0.0都是完全的零。
解决方法是使用一个for
循环并手动进行设置:
int arr[15];
int i;
for (i=0; i<6; ++i) // Set the first 6 elements in the array
arr[i] = 1; // to the value 1.
void*
,但指针类型是不同的:arr
衰减为int*
,而&arr
给出了一个类型为int(*)[15]
的指针! - Aconcagua简短回答,不行。
详细回答,memset
用于设置字节,可以对字符起作用,因为它们是单个字节,但整数不是。
wchar_t
是32位的,您可以使用wmemset()
而不是memset()
。#include<wchar.h>
...
int arr[15];
wmemset( arr, 1, 6 );
wchar_t
是16位的,因此这个技巧可能行不通。memset的第三个参数是字节数。因此,您应该设置arr[15]
的总字节数。
memset(arr, 1, sizeof(arr));
但是,也许你希望将值1设置给arr中的所有元素。那么最好在循环中设置。
for (i = 0; i < sizeof(arr)/sizeof(arr[0]); i++) {
arr[i] = 1;
}
memset()
会将每个字节设为1,所以这不符合您的预期。n * sizeof(int)
。 - mattnmemset(arr, 1, 4)
时,它变成了0x01 0x01 0x01 0x01。但你期望的是0x00 0x00 0x00 0x01
。(这取决于你的CPU架构)。 - mattn既然没有人提到它...
虽然你不能使用memset来初始化整数为值1,但是你可以使用值-1来初始化它们,并简单地改变你的逻辑以使用负值。
例如,要使用-1
初始化数组的前6个数字,你可以这样做:
memset(arr,-1,6*(sizeof int));
此外,如果您只需要进行一次初始化操作,您实际上可以在编译时声明包含值1
的数组。
int arr[15] = {1,1,1,1,1,1};
memset_pattern4
是可以实现的,它可以每次设置4个字节。memset_pattern4(your_array, your_number, sizeof(your_array));
memset
来实现此目的,除非所需的目标值是0
。memset
将目标内存区域视为字节数组而非int
数组。
一个相当流行的内存区域填充hack基于memcpy
。它关键依赖于memcpy
按正向方向复制数据的期望。
int arr[15];
arr[0] = 1;
memcpy(&arr[1], &arr[0], sizeof arr - sizeof *arr);
memcpy
在源内存区域和目标内存区域重叠时其行为是未定义的。不过你可以自己编写 memcpy
的版本,确保它向前复制数据,并以上述方式使用。但这并不值得。只需使用简单循环将数组元素设置为所需值即可。#include<stdio.h>
#include<string.h>
void printArray(int arr[], int len)
{
int i=0;
for(i=0; i<len; i++)
{
printf("%d ", arr[i]);
}
puts("");
}
int main()
{
int arrLen = 15;
int totalNoOfElementsToBeInitialized = 6;
int arr[arrLen];
printArray(arr, arrLen);
memset(arr, -1, totalNoOfElementsToBeInitialized*sizeof(arr[0]));
printArray(arr, arrLen);
memset(arr, 0, totalNoOfElementsToBeInitialized*sizeof(arr[0]));
printArray(arr, arrLen);
memset(arr, 1, totalNoOfElementsToBeInitialized*sizeof(arr[0]));
printArray(arr, arrLen);
memset(arr, 2, totalNoOfElementsToBeInitialized*sizeof(arr[0]));
printArray(arr, arrLen);
memset(arr, -2, totalNoOfElementsToBeInitialized*sizeof(arr[0]));
printArray(arr, arrLen);
return 0;
}
memset(hash, 1, cnt);
读取后,它将显示的值是16843009 = 0x01010101 = 1000000010000000100000001
而不是0x00000001
但如果你只需要 bool 或二进制值,则可以使用 C99 标准来设置 C 库。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h> //Use C99 standard for C language which supports bool variables
int main()
{
int i, cnt = 5;
bool *hash = NULL;
hash = malloc(cnt);
memset(hash, 1, cnt);
printf("Hello, World!\n");
for(i=0; i<cnt; i++)
printf("%d ", hash[i]);
return 0;
}
输出:
你好,世界!
1 1 1 1 1
Memset函数用于设置1字节的数据类型的值,但整数占用4个或更多字节,因此它不起作用,你会得到垃圾值。 它主要用于处理char和string类型的数据。
memset()
将其转换为一个字节并在整个区域内进行复制。 - Mysticial