【C语言】想要节省空间,你必须要知道——动态内存管理(附通讯录动态内存版源码)(二)

简介: 【C语言】想要节省空间,你必须要知道——动态内存管理(附通讯录动态内存版源码)(二)

3.    常见的动态内存错误


对NULL指针的解引用操作


void test()

{

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

*p = 20;//如果p的值是NULL,就会有问题

free(p);

}

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


void test()

{

int i = 0;

int *p = (int *)malloc(10*sizeof(int));

if(NULL == p)

{

exit(EXIT_FAILURE);

}

for(i=0; i<=10; i++)

{

*(p+i) = i;//当i是10的时候越界访问

}

free(p);

}


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


void test()

{

int a = 10;

int *p = &a;

free(p);//ok?

//这样不可以,会报错,非堆上的动态内存不能用free来释放

}


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


void test()

{

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

p++;

free(p);//p不再指向动态内存的起始位置,程序会挂掉

        //free释放的是p指向的空间,p必须指向所要释放空间的起始地址

}


对同一块动态内存多次释放


void test()

{

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

free(p);

free(p);//重复释放,会报错

}


动态开辟内存忘记释放(内存泄漏)


void test()

{

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

if(NULL != p)

{

*p = 20;

}

}

int main()

{

test();

//这里应该free掉开辟的动态内存空间

while(1);

}


忘记释放不再使用的动态开辟的空间会造成内存泄漏

切记: 动态开辟的空间一定要释放,并且正确释放


4.    几个经典的笔试题

  题目1:

void GetMemory(char *p)

{

p = (char *)malloc(100);

}

void Test(void) {

char *str = NULL;

GetMemory(str);

strcpy(str, "hello world");

printf(str);

}


运行Test会有什么结果?

答案是会程序会挂掉


  代码分析:

错误原因;

str传给p的时候,是值传递pstr临时拷贝,所以当malloc开辟的空间起始地址放在p中时,不会影响strstr依然为NULL

②当strNULLstrcpy想把hello world拷贝到str指向的空间时,程序就崩溃了,因为NULL指针指向的空间是不能直接访问的

图解:*

微信图片_20220415192637.png


   代码改正:


微信图片_20220415192701.png

  题目2:

char *GetMemory(void)

{

char p[] = "hello world";

return p;

}

void Test(void)

{

char *str = NULL;

str = GetMemory();

printf(str);

}


运行Test会有什么结果?

答案是


微信图片_20220415192727.png

  代码分析:

错误原因;

p局部变量(局部变量是存在栈区的),函数调用完之后就会随着函数空间的销毁而销毁,将内存空间还给操作系统

②返回的p实际上已经是一个野指针了,指向的是未知的空间


图解:


微信图片_20220415192817.png

   代码改正:


微信图片_20220415192833.png

  题目3 :

void GetMemory(char **p, int num) {

*p = (char *)malloc(num);

}

void Test(void) {

char *str = NULL;

GetMemory(&str, 100);

strcpy(str, "hello");

printf(str);

}

运行Test会有什么结果?

答案是

内存泄漏!!!!


  代码分析:

错误原因

malloc申请了内存空间,是在堆区上的,是不会自动销毁的

②如果在使用完成之后没有free掉这块空间,会造成内存泄漏,内存泄漏是指程序中已动态分配的的堆内存,由于某些原因无法释放或者未释放,造成的内存浪费


图解:


微信图片_20220415192932.png

   代码改正:


微信图片_20220415192947.png

   题目4 :

void Test(void)

{

char *str = (char *) malloc(100);

strcpy(str, "hello");

free(str);

if(str != NULL)

{

strcpy(str, "world");

printf(str);

}

}

运行Test会有什么结果?

答案是

数据非法访问


  代码分析:

错误原因;

free完之后没有将指针置空,造成了野指针的存在

野指针会导致非法访问行为


图解:

微信图片_20220415193046.png


  代码改正:

微信图片_20220415193058.png

版权声明:本文为CSDN博主「敲代码的布莱恩特」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/DerrickWestbrook/article/details/120483621

相关文章
|
1月前
|
存储 编译器 程序员
【C语言】内存布局大揭秘 ! -《堆、栈和你从未听说过的内存角落》
在C语言中,内存布局是程序运行时非常重要的概念。内存布局直接影响程序的性能、稳定性和安全性。理解C程序的内存布局,有助于编写更高效和可靠的代码。本文将详细介绍C程序的内存布局,包括代码段、数据段、堆、栈等部分,并提供相关的示例和应用。
58 5
【C语言】内存布局大揭秘 ! -《堆、栈和你从未听说过的内存角落》
|
1月前
|
存储 监控 算法
Java内存管理深度剖析:从垃圾收集到内存泄漏的全面指南####
本文深入探讨了Java虚拟机(JVM)中的内存管理机制,特别是垃圾收集(GC)的工作原理及其调优策略。不同于传统的摘要概述,本文将通过实际案例分析,揭示内存泄漏的根源与预防措施,为开发者提供实战中的优化建议,旨在帮助读者构建高效、稳定的Java应用。 ####
47 8
|
1月前
|
存储 缓存 算法
【C语言】内存管理函数详细讲解
在C语言编程中,内存管理是至关重要的。动态内存分配函数允许程序在运行时请求和释放内存,这对于处理不确定大小的数据结构至关重要。以下是C语言内存管理函数的详细讲解,包括每个函数的功能、标准格式、示例代码、代码解释及其输出。
73 6
|
2月前
|
传感器 人工智能 物联网
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发,以及面临的挑战和未来趋势,旨在帮助读者深入了解并掌握这些关键技术。
72 6
|
2月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
80 1
|
2月前
|
缓存 Prometheus 监控
Elasticsearch集群JVM调优设置合适的堆内存大小
Elasticsearch集群JVM调优设置合适的堆内存大小
501 1
|
1月前
|
存储 监控 算法
深入探索Java虚拟机(JVM)的内存管理机制
本文旨在为读者提供对Java虚拟机(JVM)内存管理机制的深入理解。通过详细解析JVM的内存结构、垃圾回收算法以及性能优化策略,本文不仅揭示了Java程序高效运行背后的原理,还为开发者提供了优化应用程序性能的实用技巧。不同于常规摘要仅概述文章大意,本文摘要将简要介绍JVM内存管理的关键点,为读者提供一个清晰的学习路线图。
|
2月前
|
Java
JVM内存参数
-Xmx[]:堆空间最大内存 -Xms[]:堆空间最小内存,一般设置成跟堆空间最大内存一样的 -Xmn[]:新生代的最大内存 -xx[use 垃圾回收器名称]:指定垃圾回收器 -xss:设置单个线程栈大小 一般设堆空间为最大可用物理地址的百分之80
|
2月前
|
Java
JVM运行时数据区(内存结构)
1)虚拟机栈:每次调用方法都会在虚拟机栈中产生一个栈帧,每个栈帧中都有方法的参数、局部变量、方法出口等信息,方法执行完毕后释放栈帧 (2)本地方法栈:为native修饰的本地方法提供的空间,在HotSpot中与虚拟机合二为一 (3)程序计数器:保存指令执行的地址,方便线程切回后能继续执行代码
29 3
|
2月前
|
存储 缓存 监控
Elasticsearch集群JVM调优堆外内存
Elasticsearch集群JVM调优堆外内存
61 1