我正在尝试读取一个包含2000万行的巨大数据集,每行中都有一个巨大的数字(实际上,我将数字存储在unsigned long long
变量中),例如:{{1} },依此类推...
我为此开发了一个简单的函数,
1774251443, 8453058335, 19672843924
由于锻炼目的,参数void read(char pathToDataset[], void **arrayToFill, int arrayLength) {
FILE *dataset = fopen(pathToDataset, "r");
if (dataset == NULL ) {
printf("Error while opening the file.\n");
exit(0); // exit failure, it closes the program
}
int i = 0;
/* Prof. suggestion: do a malloc RIGHT HERE, for allocate a
* space in memory in which store the element
* to insert in the array
*/
while (i < arrayLength && fscanf(dataset, "%llu", (unsigned long long *)&arrayToFill[i]) != EOF) {
// ONLY FOR DEBUG, it will print
//printf("line: %d.\n", i); 20ML of lines!
/* Prof. suggestion: do another malloc here,
* for each element to be read.
*/
i++;
}
printf("Read %d lines", i);
fclose(dataset);
}
的类型为arrayToFill
。每个函数都必须对通用类型执行,数组可能会填充每种类型的数据(在此示例中为巨大的数字,但可能包含巨大的字符串,整数等)。
我不明白为什么我必须打2个void**
电话,一个电话不够吗?
答案 0 :(得分:0)
对于您的第一个问题,将malloc
视为对存储N个对象的内存的调用,所有对象的大小均为S。当您拥有参数void ** arrayToFill, int arrayLength
时,您正在说的是数组将包含大小为arrayLength
的{{1}}个 个指针。那是第一个分配和对malloc的调用。
但是该数组的成员是指针,它们用于保存数组或本质上用于存储其他对象的指针。对malloc的第一次调用仅分配内存来存储每个数组成员的sizeof(void*)
,但是数组每个成员的内存都需要它自己的void*
调用。
高效的线路阅读
对于您的另一个问题,先进行大量小的内存分配,然后再释放它们(假设您会这样做,否则会泄漏很多内存),这非常慢。但是,与I / O相关任务的性能影响更多地取决于调用次数,而不是所分配的内存数量。
让程序将整个文件读入内存,并为2000万个malloc()
分配一个数组,或者分配您希望处理的许多整数。这样,您可以解析文件内容,使用unsigned long long
中的strtol
函数,然后将结果长整形复制到大型数组中。
这样,您只使用2-3个大内存分配和释放。
答案 1 :(得分:0)
我已经提出了这个POSIX解决方案,看看是否有帮助
#include <unistd.h> //for read, write, lseek
#include <stdio.h> //fprintf
#include <fcntl.h> //for open
#include <string.h> //
#include <stdlib.h> // for exit and define
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char * argv[])
{
int fd; // file descriptor
char * buffer; //pointer for the malloc
if(argc < 2)
{
fprintf(stderr, "Insert the file name as parameter\n");
exit(EXIT_FAILURE);
}
if((fd = open(argv[1], O_RDONLY)) == -1)// opens the file in read-only mode
{
fprintf(stderr, "Can't open file\n");
exit(EXIT_FAILURE);
}
off_t bytes = lseek(fd, 0, SEEK_END); // looks at how many bytes the file has
lseek(fd, 0, SEEK_SET); // returns the file pointer to the start position
buffer = malloc(sizeof(char)*bytes); // allocates enough memory for reading the file
int r = read(fd, buffer, bytes); //reads the file
if(r == -1)
{
fprintf(stdout, "Error reading\n");
exit(EXIT_FAILURE);
}
fprintf(stdout, "\n%s", buffer); // prints the file
close(fd);
exit(EXIT_SUCCESS);
}