C语言内核深度理解

calloc
void *calloc( size_t num, size_t size );
在内存的动态存储区中分配n个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL。
与malloc的区别:
calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不初始化,里边数据是随机的垃圾数据。

malloc 
void *malloc( size_t size );
 函数指向一个块连续的指定大小为size的空间,如果错误发生返回NULL。 存储空间的指针必须为堆,不能是栈。这样以便以后用free函数释放空间。

realloc 
  void *realloc( void *ptr, size_t size );
功能: 函数将ptr 对象的储存空间改变为给定的大小size。 参数size可以是任意大小,大于或小于原尺寸都可以。 返回值是指向新空间的指针,如果错误发生返回NULL

1.realloc失败的时候,返回NULL
2. realloc失败的时候,原来的内存不改变,不会释放也不会移动
3. 假如原来的内存后面还有足够多剩余内存的话,realloc的内存=原来的内存+剩余内存,realloc还是返回原来内存的地址; 假如原来的内存后面没有足够多剩余内存的话,realloc将申请新的内存,然后把原来的内存数据拷贝到新内存里,原来的内存将被free掉,realloc返回新内存的地址
4. 如果size为0,效果等同于free()。这里需要注意的是只对指针本身进行释放,例如对二维指针**a,对a调用realloc时只会释放一维,使用时谨防内存泄露。
5. 传递给realloc的指针必须是先前通过malloc(), calloc(), 或realloc()分配的
6.传递给realloc的指针可以为空,等同于malloc。

返回情况:
返回的是一个void类型的指针:调用成功。(这就要求在你需要的时候进行强制类型转换)
返回NULL:当需要扩展的大小(第二个参数)为0并且第一个参数不为NULL时。此时原内存变成“free(游离)”的了。
返回NULL:当没有足够的空间可供扩展的时候。此时,原内存空间的大小维持不变。
 

#include
#include
int main()
{
    int i;
    int*pn=(int*)malloc(5*sizeof(int));
    if (!pn)
    {
        printf("malloc fail\n");
        exit(-1);
    }
    printf("malloc %p\n",pn);
    for(i=0; i<5; i++)
        pn[i]=i;
    pn=(int*)realloc(pn,10*sizeof(int));
    if (!pn)
    {
        printf("realloc fail\n");
        exit(-1);
    }
    printf("realloc %p\n",pn);//%p以16进制打印,不过没有查到前导0的位数的设定
    for(i=5; i<10; i++)
        pn[i]=i;
    for(i=0; i<10; i++)
        printf("%3d",pn[i]);
    free(pn);
    pn = NULL;
    return 0;
}

free(ptr)
函数释放指针ptr指向的空间,以供以后使用。指针ptr 必须由先前对malloc(), calloc(), realloc()的调用返回。

java种虚拟机对内存的分配 : https://blog.csdn.net/chenpuzhen/article/details/80849199

野指针出现有三种情况:
1、使用指针前,忘了给指针变量初始化或赋值为一个有效的地址
2、不清楚某些地址空间的访问权限,但是指针试图指向这些空间,并且按照不允许的权限去操作
3、访问空间,内存越界。

三级指针写了个例子
    int a=10;
    int *p=&a;
    int **p1=&p;
    int ***b=&p1;
    printf("%d %d %d %d %d\n",*p,p,*p1,b,&b);

int const *p;
const int *p;
int const * const p;


改变const变量
int const a=10;
int *p=(int *) &a;
*p=100;
const 变量是通过编译器检查实现的,程序运行的过程种不关系变量是否是const,只要保证编译不出错,在运行的过程种去修改就可以
【但是结果并没有改变,地址确实也是指向a的地址不过还不知道为什么】【ps老师说是编译器不同的原因】


sizeof(buf)=sizeof(buf[0])

sizeof(buf)/sizeof(int)
buf数组不能buf++;

指针本身强制转换:
int a=10;
int *pa=&a;
float *pb=NULL;
pb=(float *)pa;
cout<<*pb<<' '< 将指针变量pa存放的地址转换为(float *)后,赋给了pb,pb里面的地址与pa里面的地址是相等的,但是pa放的是(int *),pb放的是(float *),
虽然都指向一个地址空间a,但是使用*pb去使用变量a的时候,会以float型的空间大小和数据结构使用a空间的值。【结果不等于a】

reverse()
是list容器下的一个方法,用重载对string char int等一般数据类型都可以实现反转,
reverse(a.begin(),a.end())
reverse(a.begin()+len1,a.begin()+len2)
reverse(a.begin(),a.end(),array_b)
复杂度是O(n)
 

你可能感兴趣的:(杂)