c++的动态内存开辟

                            

 

1.栈又叫堆栈是向下生长的,该位置存放非静态局部变量/函数参数/返回值/指针等等

2.堆用于程序运行时动态内存分配,堆是向上生长的

3.数据段--存放全局数据和静态数据

4.代码段--可执行的代码/只读常量

常见笔试题:

 

Static int s1=0;

Int     s2=1;

Int   f (int a)

{
Static int s3=3;

char*  p1 = “abcd”;

char  p2[] = “abcd”;

char*  p3 = new char p3[10];

1.计算结果

sizeof(p1) 4     //计算一个指针的大小(4字节)

sizeof(p2) 5     //a b c d \0 5个字节

strlen(p1) 4      //strlen只找\0不看类型且不计算\0

strlen(p2) 4

 

2.下面代码是否可以编译通过?如果编不过?是哪句
*p1 = '1';  //XX因为指针解引用后是常量
*p2 = '1';

 

 

3.选择题

A. 栈   B.堆  C.静态区  D.常量区

s1在哪 静态区                 s2在哪 静态区                s3在哪 静态区

p1在哪                         p2在哪                       p3在哪

*p1在哪 常量区                 *p2在哪                     *p3在哪

 

一.c语言中的动态内存管理

1.malloc

c语言提供的malloc动态开辟空间函数:void* malloc(size_t size)

这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针.

如果开辟成功则返回指向这块空间的指针.

如果开辟失败则放回一个NULL指针(注:malloc的返回值一定要做检查)

返回值的类型是void*,所以malloc函数并不知道开辟空间的类型,具体在使用时由使用者自己决定

例:

int* p1=(int*)malloc(sizeof(int)*4)

如果malloc函数中的size=0这是标准为定义的,结果如何取决于编译器。

c语言提供了另一个函数free,专门用来做动态内存的释放和回收的,函数原型如:void free(void* ptr)

free函数用来释放动态开辟的内存:

1. 如果ptr指向的空间不是动态开辟的,那么free函数的行为是未定义的。

2. 如果ptr指针指向的是NULL,则free函数什么都不做。

3. malloc和free都在stdlib.h的头文件里

2.calloc

C语言还提供了一个函数叫calloc,calloc也可以进行动态开辟内存,函数原型如下:void*  calloc(size_t num,size_t size)

函数的功能是为num个大小为size字节的元素开辟一块空间,并且把每个空间初始化为0

malloc与calloc的区别是calloc会在返回地址之前将开辟空间的每个字节初始化为0

例:

#include<stdio.h>
#include<stdlib.h>
int main()
{
int* ptr = calloc(10, sizeof(int));
if (NULL != ptr)
{
//使用空间
}
free(ptr);
ptr = NULL;
return 0;
}

如果我们对申请的内存空间有初始化要求就用calloc

3.relloc

realloc函数可以做到对动态开辟空间大小的调整,函数原型如下:

void* realloc(void* ptr,size_t size)

.ptr是要调整内存的地址

.调整之后新大小

.返回值是调整之后内存的起始位置

.这个函数在调整原内存大小的基础上,还会将原来内存上的数据搬到新空间上.

.realloc调整空间大小有两种情况:

(1) 原来空间后面有足够大的内存空间,可以支持接在原来空间上扩容(这时不用搬运原来的数据)

(2) 原来空间后面没有足够大的内存空间,不可以支持接在原来空间上扩容.这时realloc会重新找一块足够大的空间,将原来数据搬到新空间上并扩容.ptr会改变,还要释放旧的空间(这时需要搬运原来的数据到新开的空间上)

二.c++语言中的动态内存管理

c++通过new和delete或者new[]和delete[]进行动态内存管理

new和delete动态管理对象

new[]和delete[]动态管理数组

注:一定要匹配使用new和delete;new不用计算申请空间的大小它会自动计算

例:

#include<iostream>
using namespace std;
int main()
{
int* p1 = new int;//只有类型
int* p2 = new int(3);//开了一个int大小的空间并给其赋值为3
int* p3 = new int[3];//申请了3个int大小的的空间
delete p1;
delete p2;
delete []p3;
return 0;
}

malloc和free只会开空间

new先开空间再调用构造函数;delete先调用析构函数在释放空间

典型错误示范:

面试题:

malloc/free和new/delete的区别和联系:

1.他们都是动态管理内存的入口

2.malloc/free是标准库函数,new/delete是c++的操作符

3.malloc/free只是动态分配/释放空间,new/delete除了会分配空间还会调用析构函数/释放空间还会调用析构函数进行初始化和清理工作.

4.malloc/free需要手动计算类型大小并且返回类型void*,new/delete会自动计算对应类型的大小并且返回对应类型.


c++的其他内存管理(placeman版本)

void* operator new(size_t size)

void  operator delete(size_t size)

void* operator new[](size_t size)

void  operator delete[](size_t size)

标准库函数operator new()和operator delete()容易让人误解,与其他的operator(例:operator=)不同,operator new()和operator delete()不是new和delete的重载,实际上我们不能重定义new和delete的表达式(因为new和delete是操作符)


总结:

 

1. operator new()/operator delete和()operator new[]()/operator delete[]()与malloc()/free()的用法是一样的

 

2. 它们只负责分配对象/释放对象的空间,不会调用构造和析构来进行初始化和清理工作

 

3. 实际上operator new()/operator delete()和operator new[]()/operator delete[]()只是malloc()/free()的一层浅封装


由此可得new做了2件事

1.调用operator new()来分配空间

2.调用构造函数来初始化对象

由此可得delete做了2件事

1.调用析构函数来清理空间

2.调用operator delete()来释放空间

 

由此可得new[N]做了2件事

1.调用operator new()来分配空间(每次开空间会多开4字节来记录N以便知道要调用多少次析构函数)

2.调用N次构造函数来初始化对象

由此可得delete[N]做了2件事

1.调用N次析构函数来清理空间

2.调用operator delete()来释放空间


 

例:

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值