2013-12-16 27 views
0

我想知道如何声明存储的确切大小C,如果我使用array或做内存分配,如malloc,他们都需要事先决定的大小。在这种情况下,我会宣布一个非常大的尺寸来防止溢出,但它仍然有可能发生。如何在C中声明足够大小的缓冲区?

例如

如果我要拆分文本文件的话,我需要声明一个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); 
} 
+3

使用realloc的? http://www.cplusplus.com/reference/cstdlib/realloc/ – this

+3

调查realloc。 http://linux.die.net/man/3/realloc – Alec

+2

你检查文件大小。 – BLUEPIXY

回答

4

缓冲区的点(通常)是一个固定的大小,并允许您读取块中的数据。如果你正在阅读一个文件,那么你不应该把它全部放在内存中,除非你知道文件的大小,并且它不是太大。

声明一个缓冲区大小,传统上的两个电源,像2048和文件读入到它的块,然后每次读取块时间块运行的逻辑。然后你使用常量内存,可以读取任何大小的文件,而不必猜测。

一个缺点是,你可能有重叠的缓冲区的边界项目工作的问题。在这些情况下,您可能需要更加努力才能让自己的逻辑发挥作用。

或者查看mmap将整个文件虚拟地映射到内存中(但您仍然必须知道它有多大!但您可以get the files size up-front。)。

+1

+1 for'mmap' alternative –

+0

关于“事先获取文件大小”的想法,是否用'“r”'打开文件,防止其他程序追加数据? (以某种方式更改文件的长度。) – chux

+1

@chux:取决于操作系统和/或文件系统。 IIRC Windows不会让您写入正在被另一个进程使用的文件,除非您使用指定的共享权限专门打开它。在这方面,Linux通常不那么严格。 (由于大多数* nix文件系统的工作原理,在某些情况下,您甚至可以写入已删除的文件,或者删除另一个进程正在写入的文件。) – cHao

1

一个公认的答案之后的答案:

1)系统,以一天一个经典的攻击是缓冲区溢出。如果你的系统可以处理1000个字节,那么有人会尝试1001.所以,而不是一个可以处理任意大的缓冲区的解决方案,定义一个适合任务的上限。如果你正在寻找一个“名字”,1024字节应该工作。 See long name.如果代码需要重新工作,这个尺寸应该很容易调整。更长的值可能是攻击,无需正常处理。应该检测到它们并声明无效的输入。

2)不要错过树木,不见森林。我发现有趣的是,OP代码有一个经典的错误。如果getc()返回255法律价值,然后将其分配给chch可能比较EOF和停止。在关于缓冲区大小的所有讨论中,ch的大小太小。

// char ch; 
int ch; 
while((ch = fgetc(input_file)) != EOF) 

3)read_chars()应该有传递给它这样的功能可以使用这些信息的缓冲区大小:read_chars(argv[1], buffer, 1000)