将csv数据读入缓冲区。尝试读取缓冲区以将分隔符更改为null字符,并在第350万个字符后获取访问冲突。文件中有超过1400万个字符。这是什么样的伏都教吉普赛魔法?
void getCurrentData(FILE *current){
int totalProducts = 0, totalChars = 0, colCount = 0,
next = '\0', ch = '\0', productCount = 0;
long *buffer = NULL;
long i = 0;
fseek(current, 0, SEEK_END);
long fileSize = ftell(current);
rewind(current);
buffer = malloc(fileSize + 1);
fread(buffer, fileSize, 1, current);
/*replacing delimiter with null character*/
while (ch != EOF){
if (ch == ',' && next != ' '){
buffer[i - 1] = '\0';
}
ch = next;
if (next != EOF){
next = (int)(buffer)[i]; /*i was violated here*/
i++;
}
}
}
答案 0 :(得分:1)
你的fread
正在写入多头的缓冲区;所以你期望只写350万(= 1400万/ sizeof(长))项目;但是你正在访问缓冲区,就像你期望它是一个字符数组一样。访问数量超过350万的项目离开了数组的末尾,因为你将它malloc'ed为1400万字节,而不是1400万条。
此外,fread
永远不会将EOF放入写入缓冲区的结果中;它写出文件的内容不变。您必须查看fread
的返回值,以查看实际读取的内容。
答案 1 :(得分:0)
如果访问冲突是i = 3500000
而不是3,500,000
字符,则此操作位于 long
缓冲区的末尾。
由于您不知道,如果任何字符形成 long -1值,您可以轻松超越分配的缓冲区。
答案 2 :(得分:0)
因为你正在读取变量缓冲区的字符,所以它必须是char或unsigned char,不是吗?在这一行
next = (int)(buffer)[i]; /*i was violated here*/
这取决于您所使用的机器,由于缓冲区变量类型很长,因此在这种类型的访问中,您在32位机器或8位机器中访问4个字节/字符,因为缓冲区变量类型很长。