常用内存函数的一些说明

来源:互联网 发布:c语言标识符有哪些分类 编辑:程序博客网 时间:2024/05/16 01:26

(1)Memcpy

memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度。函数形式:void *memcpy(void *dbuffer,void *sbuffer,size_t n),dbuffer是需要设置的内存的目的地址,sbuffer是内存数据的源地址,n是需要填充的字节数。注意:两者所指的内存区域不能重叠。memcpy函数原型:
void* memcpy(void* pvTo, const void* pvForm, size_t size)
{
       if((pvTo!=NULL)&&( pvForm!=NULL))
      {
             unsigned char* pbTo = (unsigned char*)pvTo;
             unsigned char* pbFrom = (unsigned char*)pvFrom;
             while(size-- > 0)
            {
                  *pbTo++ = *pbFrom++;

             }

             return pvTo; 

       }
}
(2)Memmove

函数原型:void * memmove(void * dst, void * src, size_t count);与memcpy的差别在于处理内存区域重叠(overlapping)的方式不同。对于库函数来说,由于没有办法知道传递给他的内存区域的情况,所以应该使用memmove()函数。通过这个函数,可以保证不会出现任何内存块重叠问题。它的函数原型是:
void * memmove(void * dst, void * src, size_t count)
{

        //DST SRC都要转成CHAR指针(与上同)
        if ((dst <= src) || (dst >= (src + count))) //Non-Overlapping Buffers

        {
                while (count--)
                      *dst++ = *src++;
         }
         else        //Overlapping Buffers, copy from higher addresses to lower addresses
         {
                 dst += count - 1;
                 src += count - 1;
                 while (count--)
                      *dst-- = *src--;
         }
         return(dst);
}
(3) Malloc

函数形式:void * malloc(size_t size);malloc()用来配置内存空间,其大小由指定的size决定。若配置成功则返回一指针,失败则返回NULL。有一下一个实例,说明可以分配0字节内存。
int main(int argc, char* argv[])
{
      char *ptr;
      if((ptr=(char*)malloc(0))==NULL)
      {
               printf("null pointer");
      }
      else
      {
               printf("valid pointer");
       }
       return 0;
}
 这段程序的执行结果是valid pointer,也就是说就算分配0字节的内存空间,这个地址也是存在合法的而非空。设置断点也可以看到真实的分配地址。

(4)Memcmp

函数形式:int memcmp(void *buf1, void *buf2, unsigned int count);比较内存区域buf1和buf2的前count个字节(ASCII码比较)。当buf1<buf2时,返回值<0;当buf1=buf2时,返回值=0;当buf1>buf2时,返回值>0。原型:

int memcmp(const void * cs,const void * ct,size_t count)
 {
         const unsigned char *su1, *su2;
         signed char res = 0;
 
         for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
                 if ((res = *su1 - *su2) != 0)
                         break;
         return res;
 }

应用:
int main(int argc, char* argv[])
{
        char *s1="Hello, Programmers!";
        char *s2="Hello, programmers!";
        int r;      
        r=memcmp(s1,s2,strlen(s1));
        if(!r)
              printf("s1 and s2 are identical");
        else if(r<0)
              printf("s1 less than s2");
        else
              printf("s1 greater than s2");
        return 0;
}
输出是s1 less than s2。因为P的ASCII小于p,所以值是小于0。
(5) Free

别看free和delete的名字恶狠狠的,它们只是把指针所指的内存给释放掉,但并没有把指针本身干掉,指针p被free以后其地址仍然不变(非NULL),只是该地址对应的内存是垃圾,p成了“野指针”。
      如果此时不把p设置为NULL,会让人误以为p是个合法的指针。如果程序比较长,我们有时记不住p所指的内存是否已经被释放,在继续使用p之前,通常会用语句if (p != NULL)进行防错处理。很遗憾,此时if语句起不到防错作用,因为即便p不是NULL指针,它也不指向合法的内存块,是个野指针。“野指针”的成因主要有两种:
A,指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。例如
        char *p = NULL;
        char *str = (char *) malloc(100);
B,指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针。
(6)有了malloc/free为什么还要new/delete ?
      malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。 

原创粉丝点击