静态内存与动态内存 & malloc函数动态分配内存

简介: 静态内存与动态内存 & malloc函数动态分配内存

🌸栈和堆

栈和堆都是计算机中常用的内存数据结构,两者各自的特点和优缺点:

数据结构 :栈是一种线性结构,堆是一种树形结构。

内存分配方式:栈是由编译器在需要时分配的、不需要时自动清除的变量存储区。栈的内存分配和释放由系统自动管理,不需要程序员手动控制。堆是由程序员手动分配和释放的内存块,通常使用malloc()或new操作符来动态分配内存。

存储内容:栈中存储的一般是函数参数、函数调用和局部变量等。堆主要用于存储对象实例和数组。

栈的优点:分配和释放内存的操作非常高效。

栈的缺点:栈的大小有限,不能动态扩展。

堆的优点:可以动态扩展,分配的内存空间较大,存储自由。

堆的缺点:需要手动进行内存管理,如果没有及时释放分配的内存,会导致内存泄漏或内存溢出的问题。

🌸静态内存的缺陷

以传统数组为例,来简述一下静态内存的缺陷:

①在定义时,数组的大小必须是事先知道的。比如int arr[100];,并且在一般情况下,为了解决实际问题,保证数组的大小足够用,可以存储足够的变量,我们一般都会将数组的长度定义的足够长。在这样的情况下,一般就存在内存浪费的问题。

②数组存储在栈区。在程序运行期间,一个函数中定义的数组只能在该函数运行期间被其他函数调用。函数运行结束后由系统自动释放内存空间。而动态内存空间就不存在这样的问题,动态内存空间是由程序员手动分配的内存块。只要程序员不释放该内存空间,就算函数运行结束,该内存空间也不会被释放。只有当程序运行结束,这时系统为该程序分配的所有内存空间都会被释放。

🌸malloc函数的使用

malloc是一个系统函数,它是memory allocate的缩写。其中memory是“内存”的意思,allocate是“分配”的意思。所以顾名思义malloc函数的功能就是“分配内存”

malloc函数的原型:

void* malloc (size_t size);

头文件:

#include <stdlib.h>

size_t是一种整型类型,用来记录一个对象或数据类型的大小。通常通过使用sizeof操作符来获取变量或数据类型的大小,并将其赋值给size_t类型的变量。size_t类型可以用来对其他size_t类型的变量初始化,并且可以将其转换为int类型的值。类似地,ptrdiff_t是另一种整型类型,用于计算指针之间的元素个数差异

函数功能:

该函数的功能是在内存的动态存储空间即中分配一个长度为size的连续空间

函数的返回值: 一个指向所分配内存空间 起始地址指针,类型为**void ***型。

对于void*:

void *是一种特殊的指针类型,它可以指向任意类型的数据。

与其他指针类型不同,我们无需进行强制类型转换就可以将任何类型的指针赋值给void *

int *p1;
void *p2;
p2=p1;//将p2赋值给p1

这不意味无类型指针可以赋值给其他类型的指针。

一般情况下,我们都要进行强制转换。

int *p1;
void *p2;
p1=(int*)p2;

malloc函数的返回值是一个地址,这个地址就是动态分配的内存空间起始地址。如果此函数未能成功地执行,如内存空间不足,则返回空指针NULL

🌸易混淆:静态内存与静态变量

静态变量:一般是由static关键字修饰。静态变量与全局变量一样都是在静态存储区中存储的。

静态内存:静态内存是在栈中分配的,比如局部变量。

🌸malloc动态分配内存

如何区分是一个内存是静态内存还是动态内存呢?

我们一般用malloc函数进行区分。动态分配内存都有一个标志,即使用malloc函数进行区分。

如何使用malloc函数呢?

int *p=(int*)malloc(4);

它的意思是:

请求操作系统分配4个字节的内存空间,并返回动态内存的第一个字节的地址。使用强制转换(int*),将malloc函数的返回值强制转换成int *型。将此int 型指针赋值给p

这里需要注意的是:

指针变量p是在静态内存存储的。 指针变量p是用传统的方式定义的,所以是静态分配的内存空间。

而指针变量p所指向内存空间动态分配的。

相关文章
|
1月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
33 3
|
1月前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
60 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
27天前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
1月前
|
存储 Java
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
这篇文章详细地介绍了Java对象的创建过程、内存布局、对象头的MarkWord、对象的定位方式以及对象的分配策略,并深入探讨了happens-before原则以确保多线程环境下的正确同步。
53 0
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
|
1月前
|
存储 程序员 编译器
C语言——动态内存管理与内存操作函数
C语言——动态内存管理与内存操作函数
|
1月前
|
编译器 C语言 C++
详解C/C++动态内存函数(malloc、free、calloc、realloc)
详解C/C++动态内存函数(malloc、free、calloc、realloc)
154 1
|
22天前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
19 0
|
1月前
|
C语言 C++
c语言回顾-内存操作函数
c语言回顾-内存操作函数
39 0
|
1月前
|
存储 C语言 C++
来不及哀悼了,接下来上场的是C语言内存函数memcpy,memmove,memset,memcmp
本文详细介绍了C语言中的四个内存操作函数:memcpy用于无重叠复制,memmove处理重叠内存,memset用于填充特定值,memcmp用于内存区域比较。通过实例展示了它们的用法和注意事项。
64 0
|
1月前
一刻也没有为它哀悼~接下来登场的是动态内存分配的malloc与realloc以及free函数
一刻也没有为它哀悼~接下来登场的是动态内存分配的malloc与realloc以及free函数
65 0