使用read()进入无限循环的程序 1oid ReadBinary(字符*infle,HXmap*AssetMap) { int-fd; 读取的字节数,预期字节数=100000000*sizeof(字符); 字符*数据; 如果((fd=打开(仅填充,Ordu))idNUM); 免费(新消息); i++; 计数器=0; ch=数据[i]; } 免费(数据); }
在这里,我用malloc分配了100MB的数据,并传递了一个足够大(不是500MB)的926KB的文件。当我传递小文件时,它会像符咒一样读取和退出,但当我传递足够大的文件时,程序会执行到某个点,然后它就会挂起。我怀疑它要么进入了无限循环,要么内存泄漏 编辑为了更好地理解,我去掉了所有不必要的函数调用,并检查了当输入一个大文件时会发生什么。我已附上修改后的代码使用read()进入无限循环的程序 1oid ReadBinary(字符*infle,HXmap*AssetMap) { int-fd; 读取的字节数,预期字节数=100000000*sizeof(字符); 字符*数据; 如果((fd=打开(仅填充,Ordu))idNUM); 免费(新消息); i++; 计数器=0; ch=数据[i]; } 免费(数据); },c,linux,gcc,C,Linux,Gcc,在这里,我用malloc分配了100MB的数据,并传递了一个足够大(不是500MB)的926KB的文件。当我传递小文件时,它会像符咒一样读取和退出,但当我传递足够大的文件时,程序会执行到某个点,然后它就会挂起。我怀疑它要么进入了无限循环,要么内存泄漏 编辑为了更好地理解,我去掉了所有不必要的函数调用,并检查了当输入一个大文件时会发生什么。我已附上修改后的代码 1oid ReadBinary(char *infile,HXmap* AssetMap) { int fd; size_
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);
}
void ReadBinary(char*infle,HXmap*AssetMap)
{
int-fd;
读取的字节数,预期字节数=500000000*sizeof(字符);
字符*数据;
如果((fd=打开(仅填充,Ordu))<0)
错误(无输入,“%s”,填充);
if((数据=malloc(预期字节数))==NULL)
err(例如,“数据malloc”);
字节读取=读取(fd,数据,预期字节);
如果(字节数读取!=预期字节数)
printf(“只读%d,共%d字节%d\n”\
字节读取,字节预期,EX\u数据错误);
/*…对数据进行操作*/
printf(“\n”);
int i=0;
int计数器=0;
char ch=数据[0];
字符消息[512];
而(i最突出的问题是:
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);
}
除非文件的最后一个字符(或您刚刚读取的块)是\n
,否则您将经过数据数组的末尾,很可能会在过程中打碎堆栈(因为您没有检查写入消息是否在范围内)。最明显的问题是:
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);
}
除非文件的最后一个字符(或您刚刚读取的块)是\n
,否则您将经过数据
数组的末尾,很可能会在过程中破坏堆栈(因为您没有检查写入消息
是否在范围内).是否有可能在您使用的系统上,500000000比最大值大?如果是这样,预期的字节可能会滚动到更小的值。然后读取的字节也会随之滚动,并且最终占用的数据块会比您实际预期的小。结果将是,对于大数据,da的最后一个字符ta不太可能是一个“\n”,因此您在该内部循环中直接跳过它,并开始访问数据末尾以外的字符。Segfault随后出现。是否有可能在您使用的系统上,500000000大于最大大小?如果是,预期的字节可能会滚动到较小的值。然后,字节读取也会随之发生,而您最终得到的数据块比您实际期望的要小。结果是,对于大型数据,数据的最后一个字符不太可能是“\n”,因此您在该内部循环中直接跳过它,并开始访问数据末尾以外的字符。Segfult随后出现。尝试以下循环。基本上,它可以重构因此,只有一个地方的i
是递增的。有两个地方是造成问题的原因
while(ch!='\n')
{
message[counter]=ch;
i++;
counter++;
ch =data[i];
}
尝试下面的循环。基本上,它重构了您的实现,因此只有一个地方的i
是递增的。有两个地方是造成问题的原因
while(ch!='\n')
{
message[counter]=ch;
i++;
counter++;
ch =data[i];
}
sizeof(char)
是1
。没有理由在你的程序中写这个。是的,我只是为了明天而保留它,当我说,我不想分配一个char,而是一个double。只是saying@Carl在hp48上,大小(字符)为2:-)…单位为4位…@ring0-如果您使用标准C编程,则不是。语言规范要求它为1。sizeof(char)始终为1这一事实是正确的,但没有抓住要点,正如您所指出的,有充分的理由编写它。但是,最好使用sizeof(值)而不是sizeof(类型)…例如,sizeof(*数据);那么即使数据类型发生变化,您也不必更改它。sizeof(char)
是1
。没有理由在您的程序中编写它。是的,我只是为了明天而保留它,当我说,我不想分配一个char,而是分配一个double。只是saying@Carl在hp48上,大小为(字符)was 2:-)…单位为4位…@ring0-如果用标准C编程,则不是。语言规范要求它为1。sizeof(char)始终为1这一事实是正确的,但没有抓住要点,正如您所指出的,有很好的理由这样写。不过,最好使用sizeof(value)而不是sizeof(type)…例如,sizeof(*data);那么即使数据类型发生变化,您也不必对其进行更改。但是,它如何与其他类似但较小的文件一起工作?事实上,如果我将文件中的数据减少到某个阈值以下,它就可以工作perfectly@Soham可能