当前位置: 首页 > news >正文

网站 切图除尘环保设备网站模板

网站 切图,除尘环保设备网站模板,网站开发人员名片,广州比较好的网站设计接上一篇文章http://t.csdn.cn/1ONDq&#xff0c;这次我们继续讲解关于动态内存的相关知识。 一、常见的动态内存错误 1.对NULL指针进行解引用操作 #include<stdio.h> #include<stdlib.h> #include<limits.h> int main() {int* p (int*)malloc(INT_MAX/4);…

接上一篇文章http://t.csdn.cn/1ONDq,这次我们继续讲解关于动态内存的相关知识。

一、常见的动态内存错误

1.对NULL指针进行解引用操作

#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
int main()
{int* p = (int*)malloc(INT_MAX/4);*p = 20;//如果没有足够的空间导致p为NULL,就会有问题//所以必须对malloc的返回值进行判断free(p);p = NULL;return 0;
}

2.对动态开辟空间的越界访问

int main()
{int* p = (int*)malloc(40);if (p == NULL){perror("malloc");return 1;}int i = 0;for (i = 0; i < 11; i++){p[i] = 0;//原本只申请了十个整型的空间,但却访问十一个整型//所以造成越界访问}free(p);p = NULL;return 0;
}

3.对非动态开辟的内存使用free释放


int main()
{int a = 0;int* p = &a;free(p);//p不是动态开辟的空间,不能释放p = NULL;return 0;
}

4.使用free释放动态开辟内存的一部分

int main()
{int* p = (int*)malloc(40);if (p == NULL){perror("malloc");return 1;}int i = 0;for (i = 0; i < 5; i++){p[i] = 0;p++;}//p++导致p不再指向这块空间的起始地址//所以如果释放p,等于释放这块空间的一部分(后五个整型空间)//这样就会出问题free(p);p = NULL;return 0;
}

5.对同一快动态内存多次释放

int main()
{int* p = (int*)malloc(40);if (p == NULL){perror("malloc");return 1;}free(p);//。。。。。free(p);//有时候头脑不清醒就可能释放多次,这样就会出问题return 0;
}

6.动态开辟内存后忘记释放内存(最常见)

即我们动态申请内存后,最后忘记用free释放了,这样就会造成内存泄漏

二、几个关于动态内存的经典例题

例题1、代码运行结果是什么?

源代码:

void GetMemory(char* p)
{p = (char*)malloc(100);
}
void Test(void)
{char* str = NULL;GetMemory(str);strcpy(str, "hello world");printf(str);
}int main()
{Test();return 0;
}

问:这段代码运行结果会是什么呢?

例题1解答:

一是没有释放动态内存;

二是会产生这样的错误:

原因是:因为在Test函数中,把str指针置空,然后作为参数传给GesMemory函数,该函数形参用指针p接收,这样指针p也为NULL,然后给指针p动态开辟空间,函数结束,到strcpy函数,但我们注意,我们是给指针p开辟空间,但指针str是没有变的,很多伙伴想不清楚,这不是传址调用吗,p指针变了,str指针也应该跟着变呀?

实则不然,我们应该注意参数是指针也不一定是传址调用,这里是指针之间赋值,应该同时上升一段层次,这里要二级指针才算传址调用,所以指针str是不会变的,还是NULL,既然是NULL,所以就没有足够的空间能放下strcpy的第二个参数,所以报错。

例题2、代码运行结果是什么?

char* GetMemory(void)
{char p[] = "hello world";return p;
}
void Test(void)
{char* str = NULL;str = GetMemory();printf(str);
}int main()
{Test();return 0;
}

问:这段代码运行结果是什么?

例题2解答:

会产生这样的结果:

“很多小伙伴可能觉得,在GetMemory函数里面返回字符串的起始地址p,所以在Test函数里面用指针str来接收并打印,所以运行结果应该为打印字符串。”

但实则不然,我们一定要注意每个变量的生命周期,数组p的生命周期就只在函数GetMemory里面,所以当该函数return后,里面的变量所占的空间都会被自动销毁(释放),既然p的空间已经被释放了,还赋值给指针str,所以str就是个野指针,再打印str,就造成非法访问内存了。

这类问题属于:返回栈空间地址的问题

三、C/C++程序的内存开辟

如下图:

C/C++ 程序内存分配的几个区域:
1. 栈区( stack ):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。
2. 堆区( heap ):一般由程序员分配释放, 若程序员不释放,程序结束时可能由 OS 回收。分配方式类似于链表。
3. 数据段(静态区)( static )存放全局变量、静态数据。程序结束后由系统释放。
4. 代码段:存放函数体(类成员函数和全局函数)的二进制代码。
实际上普通的局部变量是在 栈区 分配空间的,栈区的特点是在上面创建的变量出了作用域就销毁。但是被static 修饰的变量存放在 数据段(静态区) ,数据段的特点是在上面创建的变量,直到程序 结束才销毁 ,所以生命周期变长。

四、柔性数组

(一)、柔性数组的概念:

也许你从来没有听说过 柔性数组( flexible array 这个概念,但是它确实是存在的。
C99 中,结构中的最后一个元素允许是未知大小的数组,这就叫做『柔性数组』成员。
如下:
//定义一:
struct S
{int a;int arr[0];
};
//定义二:
struct B
{int a;char b;int arr[];
};

(二)、柔性数组的特点:

1、 结构中的柔性数组成员前面必须至少一个其他成员。
2、 sizeof 返回的这种结构大小不包括柔性数组的内存,即sizeof只计算柔性数组前面的成员的大小。
3、 包含柔性数组成员的结构用 malloc () 函数进行内存的动态分配,并且分配的内存应该大于结构的大 小,以适应柔性数组的预期大小。

(三)、柔性数组的使用:

如下例:
struct S
{int a;int arr[];
};int main()
{//动态开辟了4+40个字节,因为柔性数组是不会被sizeof计算的//前面四个字节是给成员a的,后面四十个字节给柔性数组//因为柔性数组的大小是未知的,我们只需给出预期大小struct S* str = (struct S*)malloc(sizeof(struct S) + 40);//检查if (str == NULL){perror("malloc");return 1;}//使用str->a = 10;int i = 0;for (i = 0; i < 10; i++){str->arr[i] = i + 1;//printf("%d ", str->arr[i]);}//用realloc扩容,因为柔性数组大小未知,是可以改变的//将之前柔性数组的10个字节的大小扩容到15个struct S* p = (struct S*)realloc(str, sizeof(struct S) + 60);//检查if (p == NULL){perror("realloc");return 1;}//使用str = p;for (i = 10; i < 15; i++){str->arr[i] = i + 1;}//打印for (i = 0; i < 15; i++){printf("%d ", str->arr[i]);}//释放free(str);str = NULL;return 0;
}

用malloc函数进行开辟空间,用realloc函数进行扩容,这样数组的大小就是可变的、柔性

的,这就是柔性数组的特点。

(四)、柔性数组的优势:

1.方便内存释放:
如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,并把整个结构体返回给用户。用户调用free 可以释放结构体,但是用户并不知道这个结构体内的成员也需要 free, 所以你不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存一次性分配好了,并返回给用户一个结构体指针,用户做一次free 就可以把所有的内存也给释放掉。
2.这样有利于访问速度:
连续的内存有益于提高访问速度,也有益于减少内存碎片。(其实,我个人觉得也没多高了,反正你跑不了要用做偏移量的加法来寻址)。
http://www.yayakq.cn/news/83430/

相关文章:

  • 网站开发验收资料网站改版的费用
  • 青岛网站设计公司排名wordpress留言板模板下载
  • 随州百度网站建设wordpress後台建站
  • 什么是成交型网站建设外卖平台app开发多少钱
  • 做暧小视频xo网站app开发软件有哪些软件
  • 建站网站知乎群晖wordpress性能
  • 12个优秀平面设计素材网站做html的软件
  • 广告模板网站沈阳模板建站软件
  • 个性化网站建设开发没后台的网站怎么做优化
  • 知名品牌网站有哪些龙岗网站制作市场
  • 深圳建设工程交易服务网站软文营销的作用有哪些
  • 佛山网站建设的公司企业年金怎么提取
  • 完整网站建设案例教程php网站开发 总结
  • 建立网站的方式邢台市的做网站制作公司
  • google帐户登录网站如何做的设计app的软件
  • 请别人做网站大概要多少钱国内企业网站设计
  • 笑话网站开发标志设计说明案例
  • 性价比高的seo网站优化个人网站建设方案书范文
  • 西安SEO网站建设石家庄企业建站
  • 自己怎么做直播网站吗北京做校园的网站
  • 网站建设实践收获西安大型网站制作
  • 网站建设 架构全球室内设计公司排名
  • 贵阳58同城做网站公司东莞app下载安装
  • 做淘宝招牌软件网站龙华公司做网站
  • 苏州做网站公司有哪些页面设计软件有哪些
  • 绍兴企业网站开发软件兼职平台
  • 营销型网站建设要点淘宝网站品牌设计
  • 网站权重查询工具连云港做网站企业
  • 成都开发网站建设wordpress评论回复邮箱
  • 视频logo免费生成网站阿里云域名申请注册