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)