二、内存的分配及内存错误类型
1.内存的分配方式
内存分配方式有三种:
(1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
(2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
(3)从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。
2.new、delete/malloc、free
malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。
对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。
因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数,而是C++的运算符。
把new和delete与malloc和free混在一起用也是个坏想法。对一个用new获取来的指针调用free,或者对一个用malloc获取来的指针调用delete,理论上是可以的,但其后果是不可预测的。大家都知道“不可预测”的意思:它可能在开发阶段工作良好,在测试阶段工作良好,但也可能会最后在你最重要的客户的脸上爆炸。
3.delete和free对指针做了什么
大家都知道delete和free都是释放内存的,但是释放的内存是谁的内存?是指针变量在内存中的空间还是指针变量指向的内存?这个大家一定要弄清楚,答案是后者。
char *p = (char *) malloc(100);
strcpy(p, “hello”);
free(p); // p 所指的内存被释放,但是p所指的地址仍然不变
// 释放的概念只是一种对该段内存unlock,而并不是删掉p中所存储的地址值
…
if(p != NULL) // 没有起到防错作用,因为p是有值的
{
strcpy(p, “world”); // 出错
}
这里有很重要的两个原则:
(1)指针消亡了,并不表示它所指的内存会被自动释放。
(2)内存被释放了,并不表示指针会消亡或者成了NULL指针
因此,一旦我们用了new或malloc申请了空间,切记要用delete或free进行释放之;一旦用delete或free将动态申请的内存释放了,一定不要忘了将指针变量赋值为Null。
PS:如果申请的空间是一个动态数组,用delete释放的时候切记要在delete后面加上[],否则delete只会释放数组的第一个元素的空间,后面的都不会被释放掉,造成内存泄露。
4.动态内存不释放会怎么样
很多初学指针的人在用new/malloc申请空间后经常会忘记将空间delete/free,而且从效果上来看也没什么,甚至会认为系统会自动释放,看下例:
void main(void)
{
float *p = NULL;
while(TRUE)
{
p = new float[1000000];
cout << “eat more memory!” << endl;
}
}
这段程序运行一下,明显是一个无限循环,典型的只有new而没有delete的情况,找一个内存监控软件查看一下内存损失情况就明白了。如果强行Ctrl+C终止程序,然后关掉VC会怎么样?申请的空间会释放吗?答案是不会,一定不会!
有时我们为确保安全性喜欢将程序这样写:
void main(void)
{
float *p = NULL;
while(TRUE)
{
p = new float[1000000];
cout << “eat memory” << endl;
if(p==NULL)
exit(1);
}
}
看上去很好,即申请不成功(即内存被全部吃掉)就会调用exit(1)而将该“坏”程序杀掉,这样有用吗?不一定。
在32位系统中,操作系统支持“虚存”,内存用完了,自动用硬盘空间顶替。所以,我们在写程序动态申请内存的时候一定要注意这方面的问题。
分享到:
相关推荐
内存分配是计算机程序中的一项基本操作,指针作为编程语言中的核心概念之一,与内存分配紧密相关。指针存储内存地址,通过它可以操作内存中的数据。了解指针和内存分配对于开发稳定和高效的软件至关重要。 首先,...
在计算机编程中,动态分配二维指针内存是指在程序执行过程中动态地分配和释放内存的操作,以下是对动态分配二维指针内存的详细介绍: 1. 已知第二维的动态分配 在 C 语言中,可以使用 malloc 函数来动态分配二维...
在实际编程中,理解内存分配和释放的底层机制有助于避免内存管理错误,如缓冲区溢出、悬挂指针和内存泄漏等问题。合理使用内存管理工具和遵循良好的编程习惯,可以提高程序的稳定性和效率。虽然现代编译器和运行时...
详细剖析:指针函数、函数指针、指针数组、数组指针、双重指针、指针与动态内存分配 个人总结要点: 本质: 地址要用指针来存储,指针是用来存储地址的!!! 重难点: 指针指向的地址,也就是指针存储的地址!!...
在Linux操作系统下,动态内存分配是软件开发中一项非常重要的技术,它允许程序在运行时分配内存空间,满足各种复杂场景下的存储需求。动态内存分配主要用来解决传统数组(静态数组)所存在的问题。传统数组的长度...
例如,书中可能会讨论智能指针的使用来自动管理内存,或是介绍如何通过算法优化减少不必要的内存分配和释放。 性能优化是另一个关键议题。C++高效编程不仅仅是写出正确无误的代码,还要确保这些代码运行得足够快、...
### 模拟实现动态分区内存分配与回收算法 #### 一、背景介绍 在操作系统的设计与实现中,内存管理是非常关键的一个环节。其中,动态分区内存分配是一种常见的内存管理方式,它允许操作系统根据进程的需求动态地分配...
在编程领域,尤其是在C/C++中,动态内存分配与回收是一项关键技能,它涉及到程序运行时内存的管理和优化。动态内存分配允许程序在运行时根据需要请求和释放内存,而不是在编译时就预设固定的内存空间。这使得程序...
内存分配主要包括两种类型:静态内存分配和动态内存分配。静态内存分配在编译时完成,通常用于全局变量和静态变量。而动态内存分配则在程序运行时进行,允许程序根据需要动态地创建和销毁数据结构。 1. **静态内存...
要理解malloc函数就必须理解指针的指针,引用,指针的引用,以及动态内存分配。 程序中的内存分为两种:栈内存和动态内存。 静态声明定义变量都是在栈内存中分配空间,在栈空间中会自动释放,而动态分配内存空间是...
标题“VB 指针 内存分配”涉及的知识点包括: 1. **VB中的指针模拟**:由于VB不是强指针语言,它使用`ByRef`关键字来传递变量的内存地址,实现类似指针的效果。但这并不意味着VB提供了像C语言那样的指针运算符,如...
内存分配是其中的关键部分,确保程序可以正确地获取和释放存储空间。本资料集合详细介绍了内存管理、内存分配以及与其密切相关的指针和数组的概念。 内存管理主要包含以下几个方面: 1. 分配策略:操作系统采用...
### Delphi内存分配完全总结 #### 一、引言 Delphi作为一种强大的开发工具,在进行程序设计时,正确地管理内存对于确保程序的稳定性和性能至关重要。本文将深入探讨Delphi中的内存分配机制,包括常用的内存管理...
智能指针的核心目标是防止内存泄漏,这是C++编程中一个常见的问题,尤其是在处理动态分配的内存时。内存泄漏指的是程序在不再需要某块内存后,未能释放它,导致系统资源的浪费。 C++标准库提供了几种不同类型的智能...
**动态内存分配的类型:** 1. **最先适配算法(First Fit)**:这是最简单的内存分配策略,当请求内存时,它会从空闲块列表中选择第一个足够大的块分配给请求者。这种方法简单但可能导致大块内存被浪费。 2. **最优...
根据提供的文件内容,可以推断出文件可能涉及到计算机操作系统中的内存管理、内存分配算法以及相关的数据结构实现。文件内容包含了C语言的源代码片段,其中涉及到内存分配的两种策略:首次适应算法(First Fit)和...
在“内存分配与回收设计”代码中,读者可以期待看到如何自定义内存分配器,如何实现智能指针,以及如何使用内存池来优化内存管理的示例。这些实践将帮助开发者更好地理解和掌握内存管理的艺术,避免在实际项目中出现...
1. **内存分配与释放**:在进行内存操作前,我们需要先为数据分配内存空间。E语言提供了`malloc`或`calloc`函数来动态分配内存,而`free`函数用于释放不再使用的内存,防止内存泄漏。 2. **指针声明与初始化**:...
C++的内存分配机制是程序设计中的重要概念,它涉及到程序如何有效地管理和使用内存资源。在C++中,内存主要分为三个区域进行分配:静态存储区、栈区和堆区。 1. 静态存储区分配:这部分内存主要用于存储全局变量和...
5. **错误处理**:在执行内存分配命令时,应检查返回值是否为0,因为0通常表示分配失败。例如: ```易语言 .整数型 内存指针 = 分配内存(100) .逻辑型 成功 = (内存指针 ≠ 0) 如果 不成功 .字符串型 错误信息 ...