《IOS_C语言》程序存储区划分、动态申请内存、内存操作函数

一:程序存储区划分

1、栈区:(最低地址内存空间)一般的基本数据类型,包括数组类型、结构体类型、int\short\char····等类型,甚至是const int a=6,也是栈区的,并不是常量,也说明了const的标志并不是常量的定义,只是变量a不可以被更改的意思。

特点:可读可写,并且是先进后出,后进先出,由系统分配和回收(使用权)

如:const int a=10;//验证栈区的地址空间,对比以下,。

printf("%p\n",&a);

输出的地址是:OX7fff5fbff7dc

2、堆区:一般的动态内存分配,手动申请分配,手动释放,堆区的空间是占得最多的。

如:

char *p=malloc(10);

printf("%p\n",p);

输出的地址是:OX100206850

3、静态区:有static修饰的,并且是只能初始化一次,只有在程序退出才释放内存

如:int function(){

int a=0;

a++;

}

这个函数调用两次,结果a=1,但如果是static int a=0;则调用两次后a=2,因为只有在第一次调用时,a初始化为0,下一次调用时就不再初始化了。

如:

static int b;

printf("%p\n",b);

输出结果:OX100001028


4、常量区:常量不可以改变的,是可读,不能修改,如字符串数组:

str[]="iphone",printf("%p",str),和char *p="iphone",printf("%p",p);这两个地址是不一样的,上面打印的是字符数组型的栈区,而后面指针指向的则是常量区的地址

char *q="lanou";
    printf("%p\n",q);

输出结果:ox100000f94

5、代码区:如 void function(){``````}

(低地址内存空间)代码区:函数的语句,所有的语句编译后会生成CPU指令存储在代码区
    printf("%p\n",main);//直接打印一个函数名的地址

输出结果为:ox100000e40

二:动态申请内存(实际上在堆区执行的)

1、malloc()格式:void*malloc(unsigned int size);//void*,则返回的可以是任何类型的指针,因为是void万能指针类型,返回分配完的内存的首地址,里面的size是需要分配的字节数,可以是表达式

如:char*str=malloc(8);//申请8个字节的内存

strcpy(str,"iphone");//使用刚申请的内存空间

printf("%s\n",str);

int *arr=malloc(4);//这里可以存放一个整型的数据

short *sarr=malloc(4);//这里可以存放两个短整型的数据

Student *p=malloc(sizeof(student));//申请一个存放结构体的空间

Student*p=malloc(sizeof(Student)*5);//申请5个存放结构体的内存空间


栈内存空间的释放:(回收使用权,内存的东西并没有删除)

格式:void free(void *p)//这个就是为了避免多个指针指向同一个地址,造成冲突,因此申请了一个内存空间,必须要释放。

如:

char *p=malloc(8)//申请

free(p);//释放

p=NULL;//必须要置空,不然会变成乱指放的指针


课上练习:输出一个字符串的数字(也就是数字重新生成一个字符串)

    char str[]="jsdh232kjjl324";
    int number=sizeof(str);//计算数组的个数,但这个不是最好的,因为这是计算str的长度,不是数字的长度,以下才对
    int count=0;
    for (int i=0; i<number; i++) {//注意:(容易写错)
        if(str[i]>='0'&&str[i]<='9') {
            count++;
        }
    }
    printf("%d\n",count);
    char *q=malloc(count+1);//count +1是为了存储结束符号‘\0’
    int j=0;
    for (int i=0; i<number; i++) {
        if(str[i]>='0'&&str[i]<='9') {
            *(q+j)=str[i];//注意:(容易写错)把满足条件的数组赋给申请了存放数字的空间的指针
            j++;//注意:(容易写错成q++)不是指针自增一,会导致指向其他空间
        }
    }
    *(q+j)='\0';//注意:(容易落写)必须要加上这个结束符号
    printf("%d\n",j);//打印存放数字的指针所存放的数字个数
    printf("%s\n",q);//打印已经提取的数字所组成的字符串
    free(q);//注意:(容易落写)释放内存空间
    q=NULL;//注意:(容易落写)用完把指针放空,防止p还会指向于原来那块内存地址,如果其他在使用,则会出错!
    

//练习2(重点理解)
    //输⼊入3个学员的姓名,动态分配内存保存学员姓名,并在最后输出

char *stu[3]={0};

char temp[255]={0};//定义一个用来暂时存放姓名字符串的数组

for(inti0;i<3;i++)


  printf("please input 第%d个 words\n",i+1);

scanf("%s",temp);

unsigned long length=strlen(temp);

stu[i]=malloc(length+1);//加1是为了要存放结束符号‘\0’

strcpy(stu[i],temp);//字符串赋值只能用strcpy

//释放内存以及输出过程
    for (int i=0; i<3; i++) {
        printf("strs[%d]=%s\n",i,strs[i]);
        free(strs[i]);
        strs[i]=NULL;
    }

}


 //其他内存分配函数
    //1\calloc:
//    void *calloc(unsigned n,unsigned size);//可以申请n个size大小的空间,并且可以自动把该内存空间上的所有字节清零,但不会自动释放内存,还是需要free()来释放内存。
//    //2、realloc
//    void *realloc(void *p,unsigned newSize);//按给定的地址和大小来重新分配,也就是使用指针p重新指向重新分配的地址

三:内存操作函数


 //1、初始化内存memset(),相当于malloc()+memset()=calloc()
    char *p=malloc(10);
    p=memset(p, 0, 10);//意思是:返回
//
    //2、内存拷贝
    void *memcpy(void *dest,const void*source,size_t n);
    //如:
    void *q;
    const void *k;
    void *p=memcpy(q,k,10);
    
//    //3、比较内存mencmp(),返回值是int型,比出来时内存上内容的差值

课上练习3:定义两个整型指针,分别⽤用malloc、calloc对其分配空间保存3个元素,malloc分配的空间⽤用memset清零,随机对数组进⾏行赋值随机范围1-3,赋值后⽤用memcmp⽐比较两个数组。如果相同打印Good!否则打印Failed...

int *p=malloc(sizeof(int)*3);//定义整型指针p并且申请空间sizeof(int)这个类型的,三个则乘上3,实际上可以理解是要申请12个字节,因为3个int的元素

int *q=calloc(3,sizeof(int));//跟上面一样,只是把个数和每个的字节大小分开写

p=memset(p,0,12);

for(int a=0;i<3;i++){

   *(p+i)=arc4random()%(3-1+1)+1;

   *(q+i)=arc4random()%(3-1+1)+1;

      printf("p[%d]=%d\n",i,*(p+i));
        printf("q[%d]=%d\n",i,*(q+i));

}

int result=memcmp(p,q,12);//比较大小,如果相等,则result=0,返回值是0是,返回“Good"

//    q=memcpy(q, p, 12);//赋值函数
    int a=0;
//    错误做法:a=memcmp(p,q,3);
    a=memcmp(p,q,12);//比较两个指针数组的大小,没大没小就是相等即为0时,表示相等,比较两块内存上内容上的差值
    printf("%d\n",a);
    if (a==0) {//如果相同(比较结果为0)打印Good!否则打印Failed...
        printf("Good!\n");
    }else{
        printf("Failed!\n");
    }
    free(p);
    p=NULL;
    free(q);
    q=NULL;








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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大小小丹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值