Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >C关于为与fread一起使用的字符*分配内存的问题

C关于为与fread一起使用的字符*分配内存的问题
EN

Stack Overflow用户
提问于 2020-04-02 17:00:03
回答 2查看 147关注 0票数 2

所以我有这个密码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
FILE* file = fopen("file.txt", "r");
if(file == NULL)
{
    printf("Failed to open file.\n");
    return NULL;
}

fseek(file, 0L, SEEK_END);
long bufferSize = ftell(file);
fseek(file, 0L, SEEK_SET);

char* buffer = (char*) malloc(bufferSize);
if(buffer == NULL)
{
    printf("Failed to allocate memory for buffer.\n");
    return NULL;
}

fread(buffer, sizeof(char), bufferSize, file);
fclose(file);

当使用printf("%s",缓冲区)打印控制台时,这似乎非常好,但我想知道这是否应该导致缓冲区溢出,或者它是否错误,因为在末尾似乎没有空终止符字符。让我们假设file.txt中正好有4个字符。当计算bufferSize时,它将是一个长的值为4。因此,当我调用malloc(bufferSize)时,我将创建一个大小为4字节的缓冲区,不代表为空终止符字符。在我见过的例子中,人们都使用这样的代码来读取整个文本文件,但这难道不应该用文件中的字符来创建char*而不使用终止符字符吗?我应该使用malloc(bufferSize + 1)分配这个缓冲区并添加一个空终止符吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-04-02 17:44:55

--当用printf("%s",缓冲区)打印到控制台时,这似乎非常好。

看起来工作得很好是undefined behavior的完美表现。

应该使用malloc(bufferSize + 1)并添加一个空终止符字符来分配这个缓冲区吗?

如果希望使用指向可打印字符的连续字节的指针的%s printf格式说明符,则需要以零字节结束这些字节。或者另一种方式,%s printf格式说明符需要一个以零结尾的字节序列。否则,就会发生未定义的行为。

所以:

您的输入文件包含一个零字节,以便printf("%.*s", (int)bufferSize, buffer);停止输出。

  • 您需要自己提供一个零终止字节,以确保%s知道在哪里停止。

  • 或者您可以自己迭代字节,或者(假设bufferSizeINT_MAX低,所以很可能是)只要告诉printf何时停止指定格式说明符的精度,比如:

否则就会发生不明确的行为。

票数 3
EN

Stack Overflow用户

发布于 2020-04-02 17:26:22

根据您分配的缓冲区的大小和您的操作系统提供的分配单元的大小,分配结束时通常会有额外的字节。这意味着,根据以后如何使用内存,精确的缓冲区分配可能会导致失败,或者在分配结束时可能会出现空闲字节,而fread()不会覆盖这些字节。结果是什么呢?您可以使用具有意外大小的文件来测试您的程序,但一旦发布,程序可能会间歇性地失败。

快速修复?始终在缓冲区的末尾分配更多的空间--取决于程序如何解释字节(char、short、int、long、long、struct)。

请注意,如果字符串嵌套在struct中,则分配单元的大小不太可能将您保存,其中struct元素紧贴在一起。但奇数大小的字符串仍有空闲空间,这取决于编译器标志。

请注意,您的特定用法是查找文件的结尾,并将整个文件读入内存。您的操作系统很可能以16、32或64字节块的形式提供内存。这意味着您有1/16、1/32或1/64的机会意外地从您分配的缓冲区的末尾走出来。

建议:(0)总是分配额外的垫子,以缓冲跑到墙上。(1)考虑使用fstat()而不是ftell()?(2)考虑内存映射文件,而不是使用malloc/free和fread。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61003564

复制
相关文章
详解C# 利用反射根据类名创建类的实例对象
“反射”其实就是利用程序集的元数据信息。反射可以有很多方法,编写程序时请先导入 System.Reflection 命名空间。
zls365
2021/01/13
3.1K0
Python中动态创建类实例
简介 在Java中我们可以通过反射来根据类名创建类实例,那么在Python我们怎么实现类似功能呢? 其实在Python有一个builtin函数import,我们可以使用这个函数来在运行时动态加载一些模块。如下: def createInstance(module_name, class_name, *args, **kwargs): module_meta = __import__(module_name, globals(), locals(), [class_name]) class_m
kongxx
2018/05/14
2.4K0
iOS_Swift根据类名创建类
String需要根据项目名生成命名空间前缀+类名 再将String转换成需要生成的类型Type 再调用 Type.init() 生成对象
mikimo
2022/07/20
7350
根据类名的字符串实例化
假设你的源码定义了类CDemoClass,那么new CDemoClass()可以实例化CDemoClass。那么如果给你一个字符串“CDemoClass”,怎么实例化出CDemoClass呢?new "CDemoClass" 编译器就不让你通过了。
gaigai
2021/04/13
2.4K0
【JavaSE专栏70】自定义异常,用户根据自己的需求创建的异常类
在 Java 中,自定义异常是指用户根据自己的需求创建的异常类。Java 提供了一些预定义的异常类,如 NullPointerException、ArrayIndexOutOfBoundsException 等,但有时这些预定义的异常类并不能完全满足我们的需求。在这种情况下,我们可以通过创建自定义异常类来表示特定的异常情况。
Designer 小郑
2023/08/09
8320
【JavaSE专栏70】自定义异常,用户根据自己的需求创建的异常类
instanceof-算符是用来在运行时指出对象是否是特定类的一个实例
tea9
2022/07/16
6710
instanceof-算符是用来在运行时指出对象是否是特定类的一个实例
灵活的令人抓狂,如何在运行时修改某一个 Python 对象的类?
这样的场景你也可能遇到:调试的时候,我需要追踪某一个 Python 对象的属性变化,比如对象 someobj = SomeClass(),当 someobj 添加了一个属性( someobj.age = 14)或者修改了属性的值 (someobj.age = 18)的时候,打印这些变化。
somenzz
2022/10/25
9160
灵活的令人抓狂,如何在运行时修改某一个 Python 对象的类?
Python之用户输入
大多数程序都旨在解决最终用户的问题,为此,需要从用户那里获取一些信息。函数input()让程序暂停运行,等待用户输入一些文本。
py3study
2020/01/06
1.2K0
python用户输入(三)
name = "Li QW" #定义变量 fname = name  #fname等于name变量产生的值 print("My name is " , name,fname) name = "study"
py3study
2020/01/13
1K0
python 接收用户的输入
None是一个特殊的常量。 None和False不同。 None不是0。 None不是空字符串。 None和任何其他的数据类型比较永远返回False。 None有自己的数据类型NoneType。 你可以将None复制给任何变量,但是你不能创建其他NoneType对象。
py3study
2020/01/09
2K0
python 接收用户的输入
silverlight如何在运行时用代码动态控制(或创建)动画
silverlight做一些复杂动画时,不可能所有的动画都事先用Blend之类的设计工具"画"好(或者在设计期就在vs里编好),很多时候我们希望在运行时能动态控制动画,或者凭空动态创建一段动画. s
菩提树下的杨过
2018/01/23
1.5K0
silverlight如何在运行时用代码动态控制(或创建)动画
Python类的继承实例
类的继承可以看成对类的属性和方法的重用,能够大大的减少代码量,继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,也就是说在python中支持一个儿子继承多个爹。
王大力测试进阶之路
2019/10/25
2.6K0
python 捕获用户输入pexpect
image.png image.png
用户5760343
2019/07/31
1.3K0
python 捕获用户输入pexpect
字节码编程,Javassist篇三《使用Javassist在运行时重新加载类》
通过前面两篇 javassist 的基本内容,大体介绍了;类池(ClassPool)、类(CtClass)、属性(CtField)、方法(CtMethod),的使用方式,并通过创建不同类型的入参出参方法,基本可以掌握如何使用这样的代码结构进行字节码编程。
小傅哥
2020/04/22
2.9K1
字节码编程,Javassist篇三《使用Javassist在运行时重新加载类》
java运行时创建或修改类-JavaAgent
在运维监控系统开发过程中我们往往需要在特定的方法出入口进行记录日志、采集参数,甚至在特定场景下需要对方法的出入参数或者整个方法逻辑进行重写。目前市面上开源的APM系统主要有CAT、Zipkin、Pinpoint、SkyWalking,大都是参考Google的Dapper实现的。个人在项目中主要使用skywallking,在java、golang等多语言中有过实践,所以这里主要记录自己在java项目中使用skywallking的一些心得和笔记。
lelezc
2023/09/21
6410
java运行时创建或修改类-JavaCompiler
在Java中,你可以使用Java Compiler API动态地创建类,它可以用来编译Java源代码,这里记录下自己在实践过程中的一些知识点。
lelezc
2023/09/20
3760
【说站】python用户输入的方法
1、使用input()使程序暂停运行,等待用户输入文本,Python在获取用户的输入后,将其存储在变量中,以供用户进行使用。
很酷的站长
2022/11/24
1.1K0
【说站】python用户输入的方法
根据路径获取指定类实例并执行指定的方法
“ 最近在OA项目上和第三方做集成,我需要提供一些接口给供第三方调用,在这个过程中觉得自己测试接口很麻烦,所以想写一个JSP界面来界面化测试自己写的一些接口。”
每天学Java
2020/06/02
2.8K0
点击加载更多

相似问题

为retina iphone开发应用程序/游戏

10

我可以将我的非Retina图像转储到iOS7专用应用程序吗?

24

我可以将我的iPhone应用程序转换为API吗?

10

使应用程序对Retina显示友好

31

iphone -如何控制Retina显示屏的图像?

30
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文