方大侠 发表于 2019-4-20 21:17:19

memset的问题

本帖最后由 方大侠 于 2019-4-20 21:38 编辑

void *memset(void *s, int c, size_t n);
参数        含义
s        指向要操作的内存空间
c        指定要填充的值
n        指定要填充 s 指向空间的前 n 个字节

1 #include<stdio.h>
2 #include<math.h>
3 #include<string.h>
4 #include<stdarg.h>
5 #include<stdlib.h>
6
7 #define N 10
8
9 int main(void){
10         int *ptr = NULL;
11         int i;
12
13         ptr = (int *)malloc(N * sizeof(int));
14         if(ptr == NULL){
15               printf("调用失败\n");
16               exit(1);
17         }
18
19         memset(ptr,1,N * sizeof(int));
20
21         for(i=0;i<10;i++){
22               printf("%d ",ptr);
23         }
24         putchar('\n');
25
26         free(ptr);
27
28         return 0;
29 }

memset(ptr,0,N * sizeof(int));运行是没问题的,但是改为memset(ptr,1,N * sizeof(int));结果就乱码了。。。
MacBook-Air:mylist f$ ./test
0 0 0 0 0 0 0 0 0 0


MacBook-Air:mylist f$ ./test
16843009 16843009 16843009 16843009 16843009 16843009 16843009 16843009 16843009 16843009

难道这里有什么无符号数吗,确实是填充的整型呀。。求指导

Croper 发表于 2019-4-20 21:17:20

因为memset是按字节填充的,也就是memset(ptr,1,N)之后这段数据的每个字节都是0x01,
一个整数是4个字节,那么这个整数就是0x01010101=16843009。

方大侠 发表于 2019-4-20 21:37:55

Croper 发表于 2019-4-20 21:29
因为memset是按字节填充的,也就是memset(ptr,1,N)之后这段数据的每个字节都是0x01,
一个整数是4个字节 ...

抱歉,回答里没写好,我是写成这样的memset(ptr,1,N * sizeof(int));结果还是有问题

Croper 发表于 2019-4-20 21:57:34

方大侠 发表于 2019-4-20 21:37
抱歉,回答里没写好,我是写成这样的memset(ptr,1,N * sizeof(int));结果还是有问题

知道你写错了,我的回答就是按照memset(ptr,1,N * sizeof(int))回答的

ba21 发表于 2019-4-21 00:44:08

你这代码上的也没有谁了。

你这问题楼上正解。主要是你没有认真理解函数的用法。
常见错误
第一:memset函数按字节对内存块进行初始化,所以不能用它将int数组初始化为0和-1之外的其他值(除非该值高字节和低字节相同)。

第二:memset(void *s, int ch,size_t n);中ch实际范围应该在0~~255,因为该函数只能取ch的后八位赋值给你所输入的范围的每个字节,比如int a赋值memset(a,-1,sizeof(int )*5)与memset(a,511,sizeof(int )*5) 所赋值的结果是一样的都为-1;因为-1的二进制码为(11111111 11111111 11111111 11111111)而511的二进制码为(00000000 00000000 00000001 11111111)后八位都为(11111111),所以数组中每个字节,如a含四个字节都被赋值为(11111111),其结果为a(11111111 11111111 11111111 11111111),即a=-1,因此无论ch多大只有后八位二进制有效,而后八位二进制 的范围在(0~255)中改。而对字符数组操作时则取后八位赋值给字符数组,其八位值作为ASCII 码。

第三: 搞反了 ch 和 n 的位置.

一定要记住如果要把一个char a清零,一定是 memset(a,0,20*sizeof(char));

而不是 memset(a,20*sizeof(char),0);

第四: 过度使用memset.

这里的memset是多余的. 因为这块内存马上就被全部覆盖,清零没有意义.

另:以下情况并不多余,因某些编译器分配空间时,内存中默认值并不为0:

第五:

其实这个错误严格来讲不能算用错memset,但是它经常在使用memset的场合出现。这里错误的原因是VC函数传参过程中的指针降级,导致sizeof(a),返回的是一个something*指针类型大小的的字节数,如果是32位,就是4字节。

方大侠 发表于 2019-4-21 10:17:33

ba21 发表于 2019-4-21 00:44
你这代码上的也没有谁了。

你这问题楼上正解。主要是你没有认真理解函数的用法。


好的多谢;
原来是按字节填充的,不是按一个整型的长度填充的。。。
页: [1]
查看完整版本: memset的问题