1oid ReadBinary(char *infile,HXmap* AssetMap)
{
int fd;
size_t bytes_read, bytes_expected = 100000000*sizeof(char);
char *data;
if ((fd = open(infile,O_RDONLY)) < 0)
err(EX_NOINPUT, "%s", infile);
if ((data = malloc(bytes_expected)) == NULL)
err(EX_OSERR, "data malloc");
bytes_read = read(fd, data, bytes_expected);
if (bytes_read != bytes_expected)
printf("Read only %d of %d bytes %d\n", \
bytes_read, bytes_expected,EX_DATAERR);
/* ... operate on data ... */
printf("\n");
int i=0;
int counter=0;
char ch=data[0];
char message[512];
Message* newMessage;
while(i!=bytes_read)
{
while(ch!='\n')
{
message[counter]=ch;
i++;
counter++;
ch =data[i];
}
message[counter]='\n';
message[counter+1]='\0';
//---------------------------------------------------
newMessage = (Message*)parser(message);
MessageProcess(newMessage,AssetMap);
//--------------------------------------------------
//printf("idNUM %e\n",newMessage->idNum);
free(newMessage);
i++;
counter=0;
ch =data[i];
}
free(data);
}
这里,我已经用malloc分配了100MB的数据,并传递了一个足够大(不是500MB)大小的926KB的文件。当我传递小文件时,它会像魅力一样读取和退出,但是当我传递一个足够大的文件时,程序会执行到某个点,之后它就会挂起。我怀疑它要么进入无限循环,要么存在内存泄漏。
编辑为了更好地理解,我删除了所有不必要的函数调用,并在给出大文件作为输入时检查了会发生什么。我附上了修改后的代码
void ReadBinary(char *infile,HXmap* AssetMap)
{
int fd;
size_t bytes_read, bytes_expected = 500000000*sizeof(char);
char *data;
if ((fd = open(infile,O_RDONLY)) < 0)
err(EX_NOINPUT, "%s", infile);
if ((data = malloc(bytes_expected)) == NULL)
err(EX_OSERR, "data malloc");
bytes_read = read(fd, data, bytes_expected);
if (bytes_read != bytes_expected)
printf("Read only %d of %d bytes %d\n", \
bytes_read, bytes_expected,EX_DATAERR);
/* ... operate on data ... */
printf("\n");
int i=0;
int counter=0;
char ch=data[0];
char message[512];
while(i<=bytes_read)
{
while(ch!='\n')
{
message[counter]=ch;
i++;
counter++;
ch =data[i];
}
message[counter]='\n';
message[counter+1]='\0';
i++;
printf("idNUM \n");
counter=0;
ch =data[i];
}
free(data);
}
看起来是什么,它打印了大量的idNUM
然后 poof segmentation fault
我认为这是一个有趣的行为,对我而言,内存存在一些问题
进一步编辑我改回了i!=bytes_read
它没有给出分段错误。当我检查i<=bytes_read
时,它超过了内环的限制。(礼貌gdb)
答案 0 :(得分:3)
最明显的问题是:
while(ch!='\n')
{
message[counter]=ch;
i++;
counter++;
ch =data[i];
}
除非文件的最后一个字符(或您刚读过的块)是\n
,否则您将超过data
数组的末尾,很可能会破坏堆栈方式(因为你没有检查你对message
的写入是否在范围内)。
答案 1 :(得分:1)
尝试以下循环。基本上,它会重构您的实现,因此只有一个地方i
递增。有两个地方是造成你麻烦的原因。
#include <stdio.h>
#include <string.h>
int main()
{
const char* data = "First line\nSecond line\nThird line";
unsigned int bytes_read = strlen(data);
unsigned int i = 0;
unsigned int counter = 0;
char message[512];
while (i < bytes_read)
{
message[counter] = data[i];
++counter;
if (data[i] == '\n')
{
message[counter] = '\0';
printf("%s", message);
counter = 0;
}
++i;
}
// If data didn't end with a newline
if (counter)
{
message[counter] = '\0';
printf("%s\n", message);
}
return 0;
}
或者,你可以采取“不要重新发明轮子”的方法,并使用标准strtok
电话:
#include <stdio.h>
#include <string.h>
int main()
{
char data[] = "First line\nSecond line\nThird line";
char* message = strtok(data, "\n");
while (message)
{
printf("%s\n", message);
message = strtok(NULL, "\n");
}
return 0;
}
答案 2 :(得分:0)
在您使用的系统上,500,000,000是否可能大于最大size_t?如果是这样,bytes_expected可能会滚动到某个较小的值。然后bytes_read紧随其后,你最终会获得比你实际期望的更小的数据块。结果是,对于大数据,数据的最后一个字符不太可能是'\ n',因此您在该内循环中直接通过它并开始访问超出数据末尾的字符。 Segfault紧随其后。