使用read()进入无限循环的程序 1oid ReadBinary(字符*infle,HXmap*AssetMap) { int-fd; 读取的字节数,预期字节数=100000000*sizeof(字符); 字符*数据; 如果((fd=打开(仅填充,Ordu))idNUM); 免费(新消息); i++; 计数器=0; ch=数据[i]; } 免费(数据); }

使用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_

在这里,我用malloc分配了100MB的数据,并传递了一个足够大(不是500MB)的926KB的文件。当我传递小文件时,它会像符咒一样读取和退出,但当我传递足够大的文件时,程序会执行到某个点,然后它就会挂起。我怀疑它要么进入了无限循环,要么内存泄漏

编辑为了更好地理解,我去掉了所有不必要的函数调用,并检查了当输入一个大文件时会发生什么。我已附上修改后的代码

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可能