请教 FILE *指定的文件句柄是在堆区还是栈区的?谢谢

oracleperl 2019-12-03 12:26:25
请教 FILE *指定的文件句柄是在堆区还是栈区的?谢谢、
比如
int f ()
{
FILE * FIN=NULL;
if ((FIN=fopen("D:\TEST.TXT","rb"))==NULL)

return 0;
fclose(FIN)
}

此时我先于fclose 而return了,那么FIN会被自动关闭吗?
...全文
161 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_46684690 2021-01-14
  • 打赏
  • 举报
回复
再说一句,至于文件在内存的哪个区,那是操作系统干的事情,你的权限是把文件指针放到了栈区,间接去控制文件,操作不到真正的文件。操作文件那是操作系统干的事情,你可以通过指针打开关闭读写,fopen和fclose都调用了系统调用api函数open和close,真正干活的是操作系统的函数。
weixin_46684690 2021-01-14
  • 打赏
  • 举报
回复
我先于fclose 而return了,那么FIN会被自动关闭吗?
你迷惑的地方是这里,
1;fopen函数不只是返回了个指针,还有把文件从磁盘移动到了内存。
2;fclose函数不是为了释放FIN指针,而是把文件从内存移动到了硬盘。
3;你的写法,return之后函数内部的变量都释放了,包括你的FIN指针变量了释放,但你的fclose函数没有执行,所以文件还在内存,只是FIN指针不指向文件了而已(不是直接指向,而是FIN→文件描述符→进程文件表→系统文件表→内存的文件(内存的文件包括控制块和数据块))。
千梦一生 2019-12-03
  • 打赏
  • 举报
回复
引用 10 楼 oracleperl 的回复:
[quote=引用 8 楼 千梦一生 的回复:]
看了前几位的回答,我还以为是我知识上的一个盲点,去网上学习了一下。这类似于内存泄漏的问题。
只不过不是内存罢了,但也属于系统资源。你在进程中这么搞,确实就是泄漏了。但是如果退出进程后,操作系统会检查这些,返回你进程曾请求的所有系统资源。
关于这种泄漏,给你打个比喻

比如,你在读大学,你刚到学校,没有宿舍,你给宿管说,请给我一个房间,我要住。宿管说,ok,你去222房间,钥匙给,你自己保管好哦。好的,你每天都需要去房间过夜。此时,房间为你所用,对你而言是有意义的。
后来你谈了个女朋友,偷偷违背校规,出去租个房子住。从此,再也没有回到房间去休息过了。此时,房间对你是没有意义的,因为你不再需要,你甚至为了表决心毅然将钥匙扔掉了(函数返回,栈中地句柄、指针丢失),这回就是事实上地对你完全无意义了。可是,你没有告诉过宿管说你“得病”(借口)需要归还房间搬出去单独住(你本该先向操作系统归还资源)。而你确实又是在读学生。所以宿管坚持为你保留这个房间(由于你只申请资源却不去释放,又不退出进程,系统不敢为你释放掉资源,万一你此时此后仍在用呢)。
一年又一年,你这样的家伙多了。学校的“空房间“也挺多的(泄漏地资源),但由于你还没毕业,也不归还钥匙。所以学校在招生的时候考虑到房间满了,就很遗憾的无法容纳许多学生。
直到你这家伙毕业,学校才会去统一清理掉你过去要求(申请)的一切资源

比喻很形象,我要问的是,中间我需要return,也就是delete之前return
那么我现在想的就是在return之前再写个delete了[/quote]

总结一点就是,释放不释放是根据你业务需求来的,你需要在学校房间住,这是需求决定的。需要用就不能释放,不需要了就要释放掉,而那个钥匙是你-->那个房间唯一的联系。没释放之前切勿丢失(认为是个地址就好),否则,就是内存泄漏
千梦一生 2019-12-03
  • 打赏
  • 举报
回复
引用 10 楼 oracleperl 的回复:
[quote=引用 8 楼 千梦一生 的回复:]
看了前几位的回答,我还以为是我知识上的一个盲点,去网上学习了一下。这类似于内存泄漏的问题。
只不过不是内存罢了,但也属于系统资源。你在进程中这么搞,确实就是泄漏了。但是如果退出进程后,操作系统会检查这些,返回你进程曾请求的所有系统资源。
关于这种泄漏,给你打个比喻

比如,你在读大学,你刚到学校,没有宿舍,你给宿管说,请给我一个房间,我要住。宿管说,ok,你去222房间,钥匙给,你自己保管好哦。好的,你每天都需要去房间过夜。此时,房间为你所用,对你而言是有意义的。
后来你谈了个女朋友,偷偷违背校规,出去租个房子住。从此,再也没有回到房间去休息过了。此时,房间对你是没有意义的,因为你不再需要,你甚至为了表决心毅然将钥匙扔掉了(函数返回,栈中地句柄、指针丢失),这回就是事实上地对你完全无意义了。可是,你没有告诉过宿管说你“得病”(借口)需要归还房间搬出去单独住(你本该先向操作系统归还资源)。而你确实又是在读学生。所以宿管坚持为你保留这个房间(由于你只申请资源却不去释放,又不退出进程,系统不敢为你释放掉资源,万一你此时此后仍在用呢)。
一年又一年,你这样的家伙多了。学校的“空房间“也挺多的(泄漏地资源),但由于你还没毕业,也不归还钥匙。所以学校在招生的时候考虑到房间满了,就很遗憾的无法容纳许多学生。
直到你这家伙毕业,学校才会去统一清理掉你过去要求(申请)的一切资源

比喻很形象,我要问的是,中间我需要return,也就是delete之前return
那么我现在想的就是在return之前再写个delete了[/quote]

通常的方法吧
1.外面new一段空间(或者说对象)把对象传进来,你函数内部搞好然后return。然后外面delete。
2.new...XX
if (....)
{
delete [] XX;
return -1
}
delete [] XX;
谁创建谁delete。但其实,这并不重要,仅仅是比较规范,重要的是:
切记保管好你new后它给你的凭据(那个地址、变量名云云:或者说是前面比喻的钥匙,毕竟退房得还钥匙进房也得有钥匙,不然可能退不了房间,或者再也进不去房间了)。 你随时随地可以delete或者free掉它。
oracleperl 2019-12-03
  • 打赏
  • 举报
回复
引用 8 楼 千梦一生 的回复:
看了前几位的回答,我还以为是我知识上的一个盲点,去网上学习了一下。这类似于内存泄漏的问题。 只不过不是内存罢了,但也属于系统资源。你在进程中这么搞,确实就是泄漏了。但是如果退出进程后,操作系统会检查这些,返回你进程曾请求的所有系统资源。 关于这种泄漏,给你打个比喻 比如,你在读大学,你刚到学校,没有宿舍,你给宿管说,请给我一个房间,我要住。宿管说,ok,你去222房间,钥匙给,你自己保管好哦。好的,你每天都需要去房间过夜。此时,房间为你所用,对你而言是有意义的。 后来你谈了个女朋友,偷偷违背校规,出去租个房子住。从此,再也没有回到房间去休息过了。此时,房间对你是没有意义的,因为你不再需要,你甚至为了表决心毅然将钥匙扔掉了(函数返回,栈中地句柄、指针丢失),这回就是事实上地对你完全无意义了。可是,你没有告诉过宿管说你“得病”(借口)需要归还房间搬出去单独住(你本该先向操作系统归还资源)。而你确实又是在读学生。所以宿管坚持为你保留这个房间(由于你只申请资源却不去释放,又不退出进程,系统不敢为你释放掉资源,万一你此时此后仍在用呢)。 一年又一年,你这样的家伙多了。学校的“空房间“也挺多的(泄漏地资源),但由于你还没毕业,也不归还钥匙。所以学校在招生的时候考虑到房间满了,就很遗憾的无法容纳许多学生。 直到你这家伙毕业,学校才会去统一清理掉你过去要求(申请)的一切资源
比喻很形象,我要问的是,中间我需要return,也就是delete之前return 那么我现在想的就是在return之前再写个delete了
寻开心 2019-12-03
  • 打赏
  • 举报
回复
文件指针是系统管理的句柄,fclose是通知系统释放它,你没有通知,系统自然不会释放

函数里面用的申请出来的动态指针,也就是malloc出来的,是要根据自己的需要在函数里面,或者其他的地方调用free来释放
自己定义的静态数组什么的,是在退出函数的时候系统帮你释放的
千梦一生 2019-12-03
  • 打赏
  • 举报
回复
看了前几位的回答,我还以为是我知识上的一个盲点,去网上学习了一下。这类似于内存泄漏的问题。
只不过不是内存罢了,但也属于系统资源。你在进程中这么搞,确实就是泄漏了。但是如果退出进程后,操作系统会检查这些,返回你进程曾请求的所有系统资源。
关于这种泄漏,给你打个比喻

比如,你在读大学,你刚到学校,没有宿舍,你给宿管说,请给我一个房间,我要住。宿管说,ok,你去222房间,钥匙给,你自己保管好哦。好的,你每天都需要去房间过夜。此时,房间为你所用,对你而言是有意义的。
后来你谈了个女朋友,偷偷违背校规,出去租个房子住。从此,再也没有回到房间去休息过了。此时,房间对你是没有意义的,因为你不再需要,你甚至为了表决心毅然将钥匙扔掉了(函数返回,栈中地句柄、指针丢失),这回就是事实上地对你完全无意义了。可是,你没有告诉过宿管说你“得病”(借口)需要归还房间搬出去单独住(你本该先向操作系统归还资源)。而你确实又是在读学生。所以宿管坚持为你保留这个房间(由于你只申请资源却不去释放,又不退出进程,系统不敢为你释放掉资源,万一你此时此后仍在用呢)。
一年又一年,你这样的家伙多了。学校的“空房间“也挺多的(泄漏地资源),但由于你还没毕业,也不归还钥匙。所以学校在招生的时候考虑到房间满了,就很遗憾的无法容纳许多学生。
直到你这家伙毕业,学校才会去统一清理掉你过去要求(申请)的一切资源
oracleperl 2019-12-03
  • 打赏
  • 举报
回复
引用 4 楼 寻开心 的回复:
函数结束后,其内部变量占用的空间是被释放了 但是内部变量如果是指针类型,那么它指向的内存并没有被自动释放 最典型例子就是动态指针 你在A函数体内定义一个指针类型变量,malloc空间给它, 在没有调用free之前,这个空间一直存在 你从A函数退出,只要free没有调用, 这个申请的空间依然是存在的
谢谢,函数里定义的指针,退出函数前都要手工释放吗? 比如如下代码不合理?会造成内存泄露? int f() { char* pt = NULL; pt=某字符数组; return 0; }
oracleperl 2019-12-03
  • 打赏
  • 举报
回复
引用 5 楼 636f6c696e 的回复:
两个概念不要混淆,你的写法不是占内存泄露而是句柄泄露 操作系统的句柄数是有限制的, 如果所有人句柄申请后都不释放,最后会申请不到句柄
谢谢,如果我程序结束了,但是程序里没有fclose 句柄会释放吗?
636f6c696e 2019-12-03
  • 打赏
  • 举报
回复
两个概念不要混淆,你的写法不是占内存泄露而是句柄泄露 操作系统的句柄数是有限制的, 如果所有人句柄申请后都不释放,最后会申请不到句柄
寻开心 2019-12-03
  • 打赏
  • 举报
回复
函数结束后,其内部变量占用的空间是被释放了
但是内部变量如果是指针类型,那么它指向的内存并没有被自动释放

最典型例子就是动态指针
你在A函数体内定义一个指针类型变量,malloc空间给它, 在没有调用free之前,这个空间一直存在
你从A函数退出,只要free没有调用, 这个申请的空间依然是存在的
oracleperl 2019-12-03
  • 打赏
  • 举报
回复
引用 2 楼 寻开心 的回复:
文件句柄是操作系统管理的,你只是定义了一个变量自己保存它而已,这个变量处于栈当中,所有的局部变量都是在栈当中的 不会关闭, 并且占据系统的文件句柄管理资源
可我这个是局部变量啊,不是说函数返回了,函数内的局部变量都释放了吗?
寻开心 2019-12-03
  • 打赏
  • 举报
回复
文件句柄是操作系统管理的,你只是定义了一个变量自己保存它而已,这个变量处于栈当中,所有的局部变量都是在栈当中的
不会关闭, 并且占据系统的文件句柄管理资源
mymtom 2019-12-03
  • 打赏
  • 举报
回复
1. 栈
2. 不会

64,683

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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