内存管理问题

xiaofeng_yan 2008-02-25 09:56:49
/*test.c*/
#include <stdio.h>
#include <stdlib.h>
#define SIZE 16
int main ()
{
char *p;
p = malloc (SIZE*sizeof(char));
free(p);
p[0] = 'a';
printf("%c\n",p[0]);
return 0;
}


gcc test.c生成a.out
[yxf@localhost mem]$ ./a.out
a
这是什么原因,我已经在程序中先free了阿?
...全文
145 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
zpp520 2008-02-26
  • 打赏
  • 举报
回复
楼上说的很清楚了
zzyjsjcom 2008-02-25
  • 打赏
  • 举报
回复
free 后 最好把指针置空
zh1369 2008-02-25
  • 打赏
  • 举报
回复
没抱错 != 没有错。
p 好像叫 野指针了吧!
imasmallbird 2008-02-25
  • 打赏
  • 举报
回复
动态开辟并释放后,一定把指针清成NULL,否则有时就会出现这种情况,
楼上的几个说的十分详细了!!
sheenl 2008-02-25
  • 打赏
  • 举报
回复
非法使用内存, 又没说一定会崩溃,只是可能会崩溃。

jixingzhong 2008-02-25
  • 打赏
  • 举报
回复
要明白 free 动作, 它只是告诉系统,这块内存我(当前进程)使用完毕,可以收回并分配给其他进程使用。
这里有两点:
1 它不改写里面的值,所以暂时,还是 ‘a’
2 在没有被其他进程使用之前,访问这个内存空间不会有冲突

所以,在一定的几率下,free后依然可以获得 a 字符

但是这样的操作是无法保证其正确性的,
因为free后什么时候会被使用,被改写,都是无法预知的
Mnky 2008-02-25
  • 打赏
  • 举报
回复
C并不明确禁止use-after-free的情形(尽管这是一类很隐蔽而严重的错误)。这是因为C的malloc系列函数实际上是操作系统内存管理接口的一个封装,在free时,通常并不同时释放进程占用的内存页,相反,它仅仅将这部分内存在malloc内部结构中标记为可再分配。
如果有后续的内存访问,由于内存页仍然是可读写的权限,因此不致导致访问异常。然而,由于malloc已经不知道这部分内存仍在使用,因此,后续的malloc操作有可能将这部分内存再次分配给程序的其它部分使用。由于仍然保有指向此内存块的指针,程序将陷入十分危险的状态,有可能崩溃,也有可能表面上看什么事也没有。

建议:为防止非法使用free后的内存,最好在free(p)后加上p=NULL,这是个好习惯。
skefer 2008-02-25
  • 打赏
  • 举报
回复
是不是在
malloc (SIZE*sizeof(char));
前面加(char *),
因为malloc()的返回类型是void。
skefer 2008-02-25
  • 打赏
  • 举报
回复
free后是应该把指针置空
否则用if(p != NULL)
是无法判别野指针的
因为free()只是说p指向的内存是无用的(系统收回了此段内存)
但p并不是NULL
第一章 走进linux 1.1 GNU与Linux的成长 1.2 Linux的开发模式和运作机制 1.3走进Linux内核 1.4 分析Linux内核的意义 1.5 Linux内核结构 1.6 Linux内核源代码 1.7 Linux内核源代码分析工具 第二章 Linux运行的硬件基础 2.1 i386的寄存器 2.2 内存地址 2.3 段机制和描述符 2.4 分页机制 2.5 Linux中的分页机制 2.6 Linux中的汇编语言 第三章中断机制 3.1 中断基本知识 3.2中断描述符表的初始化 3.3异常处理 3.4 中断处理 3.5中断的后半部分处理机制 第四章 进程描述 4.1 进程和程序(Process and Program) 4.2 Linux中的进程概述 4.3 task_struct结构描述 4.4 task_struct结构在内存中的存放 4.5 进程组织的方式 4.6 内核线程 4.7 进程的权能 4.8 内核同步 第五章进程调度 5.1 Linux时间系统 5.2 时钟中断 5.3 Linux的调度程序-Schedule( ) 5.4 进程切换 第六章 Linux内存管理 6.1 Linux的内存管理概述 6.2 Linux内存管理的初始化 6.3 内存的分配和回收 6.4 地址映射机制 6.5 请页机制 6.6 交换机制 6.7 缓存和刷新机制 6.8 进程的创建和执行 第七章 进程间通信 7.1 管道 7.2 信号(signal) 7.3 System V 的IPC机制 第八章 虚拟文件系统 8.1 概述 8.2 VFS中的数据结构 8.3 高速缓存 8.4 文件系统的注册、安装与拆卸 8.5 限额机制 8.6 具体文件系统举例 8.7 文件系统的系统调用 8 .8 Linux2.4文件系统的移植问题 第九章 Ext2文件系统 9.1 基本概念 9.2 Ext2的磁盘布局和数据结构 9.3 文件的访问权限和安全 9.4 链接文件 9.5 分配策略 第十章 模块机制 10.1 概述 10.2 实现机制 10.3 模块的装入和卸载 10.4 内核版本 10.5 编写内核模块 第十一章 设备驱动程序 11.1 概述 11.2 设备驱动基础 11.3 块设备驱动程序 11.4 字符设备驱动程序 第十二章 网络 12.1 概述 12.2 网络协议 12.3 套接字(socket) 12.4 套接字缓冲区(sk_buff) 12.5 网络设备接口 第十三章 启动系统 13.1 初始化流程 13.2 初始化的任务 13.3 Linux 的Boot Loarder 13.4 进入操作系统 13.5 main.c中的初始化 13.6 建立init进程 附录: 1 Linux 2.4内核API 2.1 驱动程序的基本函数 2.2 双向循环链表的操作 2.3 基本C库函数 2.4 Linux内存管理中Slab缓冲区 2.5 Linux中的VFS 2.6 Linux的连网 2.7 网络设备支持 2.8 模块支持 2.9 硬件接口 2.10 块设备 2.11 USB 设备

70,022

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧