我想知道如何在C中声明存储的确切大小,如果我使用array
或执行内存分配,例如malloc
,他们都需要先决定大小。在这种情况下,我将声明一个非常大的大小以防止溢出,但它仍有可能发生。
例如
如果我想将文本文件拆分为单词,我需要声明char **
来存储单词字符串,但我不知道会分割多少单词?
如果我想将文件内容读入数组
我需要声明一个大缓冲区来存储
buffer = malloc(sizeof(char)*1000);
任何更好或正确的解决方案?感谢
#include <stdio.h>
#include <stdlib.h>
void read_chars(char * file_name ,char * buffer);
int main(int argc ,char * argv[])
{
char * buffer ;
buffer = malloc(sizeof(char)*1000);
read_chars(argv[1],buffer);
printf("%s",buffer);
}
void read_chars(char * file_name ,char * buffer)
{
FILE * input_file ;
input_file = fopen(file_name,"r");
int i = 0;
char ch;
while((ch = fgetc(input_file)) != EOF)
{
*(buffer+i) = ch;
i++;
}
*(buffer+i) = '\0';
fclose(input_file);
}
答案 0 :(得分:4)
缓冲区的点(通常)是固定大小,允许您以块的形式读取数据。如果你正在阅读一个文件,那么除非你知道文件的大小并且它不是太大,否则你不应该把它全部保存在内存中。
声明缓冲区大小,传统上是2的幂,如2048,并以块的形式将文件读入其中,然后在每次读取块时在块上运行逻辑。然后你使用常量内存,可以读取任何大小的文件,而不必猜测。
缺点是您可能在处理与缓冲区边界重叠的项目时遇到问题。在这些情况下,您可能需要更加努力地使您的逻辑工作。
或者看看mmap
虚拟地将整个文件映射到内存中(你仍然需要知道它有多大!但你可以get the files size up-front。)。
答案 1 :(得分:2)
接受答案后的回答:
1)对系统的典型攻击是缓冲区溢出。如果你的系统可以处理1000个字节,有人会尝试1001.因此,不是一个可以处理任意大缓冲区的解决方案,而是定义一个面向任务的上限。如果一个人正在寻找“名称”,1024字节应该工作。 See long name.如果代码需要重新工作,这个大小应该很容易调整。较长的值可能是攻击,无需正常处理。应检测它们并将其声明为无效输入。
2)千万不要错过树林里的森林。我发现OP代码有一个经典错误很有趣。如果getc()
返回合法值255,则将其分配给ch
,ch
可以与EOF
进行比较并停止。在关于缓冲区大小的所有这些争论中,ch
的大小太小了。
// char ch;
int ch;
while((ch = fgetc(input_file)) != EOF)
3)read_chars()
应该将缓冲区大小传递给它,以便函数可以使用该信息:read_chars(argv[1], buffer, 1000)
。