malloc和memset的理解

本文主要介绍了C++中的动态内存分配函数malloc和内存设置函数memset。malloc用于分配指定字节数的内存块,返回void指针,需要类型转换。memset则用于将内存区域的每个字节设置为特定值,常用于初始化内存。文章还对比了malloc与new的区别,malloc分配的内存未初始化,而new可以自动计算类型大小并初始化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思科某笔试题
int main
{
	char *p1 = "hello";
	char *p2;
	p2 = (char *)malloc(20);
	//p2 = (char *)malloc(sizeof(char));
	memset(p2,0,20);
	while(*p2++ = *p1++)
		printf("%s\n",p2);
        return 0;
}
结果输出5个空的换行。

这里主要考察++,*,=这些运算符的优先级。

注意点;memset是对字节操作的,memset(p2, 0, 20),这个 把20个字节空间全部赋值为assic为0的值,就是null。




zz: http://blog.youkuaiyun.com/xw13106209/article/details/4962479

一、原型:extern void *malloc(unsigned int num_bytes);

头文件:#include <malloc.h> 或 #include <alloc.h> (注意:alloc.h 与 malloc.h 的内容是完全一致的。)

功能:分配长度为num_bytes字节的内存块

说明:如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。

当内存不再使用时,应使用free()函数将内存块释放。

 

举例:

[c-sharp]  view plain copy
  1. #include<stdio.h>  
  2. #include<malloc.h>  
  3. int main()  
  4. {  
  5.     char *p;  
  6.    
  7.     p=(char *)malloc(100);  
  8.     if(p)  
  9.         printf("Memory Allocated at: %x/n",p);  
  10.     else  
  11.         printf("Not Enough Memory!/n");  
  12.     free(p);  
  13.     return 0;  
  14. }  

 

 

二、函数声明(函数原型):

  void *malloc(int size);

  说明:malloc 向系统申请分配指定size个字节的内存空间。返回类型是 void* 类型。void* 表示未确定类型的指针。C,C++规定,void* 类型可以强制转换为任何其它类型的指针。这个在MSDN上可以找到相关的解释,具体内容如下:

     

malloc returns a void pointer to the allocated space, or NULL if there is insufficient memory available. To return a pointer to a type other than void, use a type cast on the return value. The storage space pointed to by the return value is guaranteed to be suitably aligned for storage of any type of object. If size is 0, mallocallocates a zero-length item in the heap and returns a valid pointer to that item. Always check the return frommalloc, even if the amount of memory requested is small.

三、malloc与new的不同点

  从函数声明上可以看出。malloc 和 new 至少有两个不同: new 返回指定类型的指针,并且可以自动计算所需要大小。比如:

      int *p;

  p = new int; //返回类型为int* 类型(整数型指针),分配大小为 sizeof(int);

  或:

  int* parr;

  parr = new int [100]; //返回类型为 int* 类型(整数型指针),分配大小为 sizeof(int) * 100;

 

    而 malloc 则必须由我们计算要字节数,并且在返回后强行转换为实际类型的指针。

    int* p;

  p = (int *) malloc (sizeof(int));

 

  第一、malloc 函数返回的是 void * 类型,如果你写成:p = malloc (sizeof(int)); 则程序无法通过编译,报错:“不能将 void* 赋值给 int * 类型变量”。所以必须通过 (int *) 来将强制转换。

  第二、函数的实参为 sizeof(int) ,用于指明一个整型数据需要的大小。如果你写成:

  int* p = (int *) malloc (1);

  代码也能通过编译,但事实上只分配了1个字节大小的内存空间,当你往里头存入一个整数,就会有3个字节无家可归,而直接“住进邻居家”!造成的结果是后面的内存中原有数据内容全部被清空。

  malloc 也可以达到 new [] 的效果,申请出一段连续的内存,方法无非是指定你所需要内存大小。

  比如想分配100个int类型的空间:

  int* p = (int *) malloc ( sizeof(int) * 100 ); //分配可以放得下100个整数的内存空间。

  另外有一点不能直接看出的区别是,malloc 只管分配内存,并不能对所得的内存进行初始化,所以得到的一片新内存中,其值将是随机的。

  除了分配及最后释放的方法不一样以外,通过malloc或new得到指针,在其它操作上保持一致。

 

 总结:

malloc()函数其实就在内存中找一片指定大小的空间,然后将这个空间的首地址范围给一个指针变量,这里的指针变量可以是一个单独的指针,也可以是一个数组的首地址,这要看malloc()函数中参数size的具体内容。我们这里malloc分配的内存空间在逻辑上连续的,而在物理上可以连续也可以不连续。对于我们程序员来说,我们关注的是逻辑上的连续,因为操作系统会帮我们安排内存分配,所以我们使用起来就可以当做是连续的。


zz:http://www.cnblogs.com/lebronjames/archive/2010/07/04/1770987.html

功 能

  将s所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值,
  块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作,
  其返回值为指向S的指针。

用 法

  void *memset(void *s, int ch, unsigned n);

程序例

  #include <string.h>
  #include <stdio.h>
  #include <memory.h>

memset

  int main(void)
  {
  char buffer[] = "Hello world\n";
  printf("Buffer before memset: %s\n", buffer);
  memset(buffer, '*', strlen(buffer) );
  printf("Buffer after memset: %s\n", buffer);
  return 0;
  }
  输出结果:
  Buffer before memset: Hello world
  Buffer after memset: ***********
  编译平台:
  Microsoft Visual C++ 6.0
  也不一定就是把内容全部设置为ch指定的ASCII值,而且该处的ch可为int或者其他类型,并不一定要是char类型。例如下面这样:
  int array[5] = {1,4,3,5,2};
  for(int i = 0; i < 5; i++)
  cout<<array[i]<<" ";
  cout<<endl;
  memset(array,0,5*sizeof(int));
  for(int k = 0; k < 5; k++)
  cout<<array[k]<<" ";
  cout<<endl;
  输出的结果就是:
  1 4 3 5 2
  0 0 0 0 0
  后面的表大小的参数是以字节为单位,所以,对于int或其他的就并不是都乘默认的1(字符型)了。而且不同的机器上int的大小也可能不同,所以最好用sizeof()。
  
  要注意的是,memset是对字节进行操作 ,所以上述程序如果改为
  int array[5] = {1,4,3,5,2};
  for(int i = 0; i < 5; i++)
  cout<<array[i]<<" ";
  cout<<endl;
  memset(array,1,5*sizeof(int));// 注意 这里与上面的程序不同
  for(int k = 0; k < 5; k++)
  cout<<array[k]<<" ";
  cout<<endl;
  输出的结果就是:
  1 4 3 5 2
  16843009 16843009 16843009 16843009 16843009
  为什么呢?
  因为memset是以字节为单位就是对array指向的内存的5个字节进行赋值,每个都用ASCII为1的字符去填充,转为二进制后,1就是00000001,占一个字节。一个INT元素是4字节,合一起就是00000001000000010000000100000001,就等于16843009,就完成了对一个INT元素的赋值了。
  所以用memset对非字符型数组赋初值是不可取的!
  例如有一个结构体Some x,可以这样清零:
  memset( &x, 0, sizeof(Some) );
  如果是一个结构体的数组Some x[10],可以这样:
  memset( x, 0, sizeof(Some)*10 );

memset函数详细说明

  1。void *memset(void *s,int c,size_t n)
  总的作用:将已开辟内存空间 s 的首 n 个字节的值设为值 c。
  2。例子
  main(){
  char *s="Golden Global View";
  clrscr();
  memset(s,'G',6);//貌似这里有点问题//
  printf("%s",s);
  getchar();
  return 0;
  } 
  【应该是没有问题的,字符串指针一样可以,并不是只读内存,可以正常运行】
  3。memset() 函数常用于内存空间初始化。如:
  char str[100];
  memset(str,0,100);
  4。memset()的深刻内涵:用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为‘memset(a, '\0', sizeof(a));
  memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度;例:
  char a[100], b[50];
  memcpy(b, a, sizeof(b)); //注意如用sizeof(a),会造成b的内存地址溢出。
  strcpy就只能拷贝字符串了,它遇到'\0'就结束拷贝;例:
  char a[100], b[50];
  strcpy(a,b);
  如用strcpy(b,a),要注意a中的字符串长度(第一个‘\0’之前)是否超过50位,如超过,则会造成b的内存地址溢出。
  5.补充:某人的一点心得
  memset可以方便的清空一个结构类型的变量或数组。
  如:
  struct sample_struct
  {
  char csName[16];
  int iSeq;
  int iType;
  };
  对于变量
  struct sample_strcut stTest;
  一般情况下,清空stTest的方法:
  stTest.csName[0]='\0';
  stTest.iSeq=0;
  stTest.iType=0;
  用memset就非常方便:
  memset(&stTest,0,sizeof(struct sample_struct));
  如果是数组:
  struct sample_struct TEST[10];
  则
  memset(TEST,0,sizeof(struct sample_struct)*10);




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值