【问题标题】:C realloc errorC 重新分配错误
【发布时间】:2014-12-14 06:53:31
【问题描述】:

我在使用 realloc 打开内存时遇到问题。我正在尝试为从文件中读取的字符串数组动态分配内存。我想要做的是,使用 fgets 读取一行的前 200 个字符,如果这 200 个字符有新行,我继续下一行。我有这个工作得很好而且花花公子。我的问题是当前 200 个字符没有换行符时,我试图将另外 200 个字符的空间重新分配给字符串,然后将新的 200 个字符连接到旧的字符上,直到它包含一个新行。经测试,在第二个realloc上出现glibc error of invalid size。

我调用 realloc 是不是错了?我已经阅读了手册页并将其用作参考,而我用作参考的书说因为它是 sizeof(char) ,所以我不需要实际包含其大小。谁能指出我哪里出错了?非常感谢您的帮助。

while( (!feof(file)) && lineCount < 11999 ) {               //will loop til end of file
    lines[index] = malloc(201*sizeof(char));                //give 201 spaces for the pointer at index
    fgets(lines[index], 200, file);                         //gets first 200 chars
    temp = strchr(lines[index], '\n');                     //set temp for while loop
       while(temp == NULL){                                //while the string doesnt have \n
           printf("string doesn't have have a newline character\n");
           lines[index]=realloc(lines[index],200);             //lines[index] now has 200 extra space
           printf("added extra space\n");
           fgets(temp2,200,file);                                  //read next 200 chars into temp
           printf("%s",temp2);                                     //for testing print next 200 lines
           temp=strchr(temp2,'\n');                            //for while loop, check if temp has "\n"
           strcat(lines[index],temp2);                              //concat string onto end
           printf("This is lines after cat\n\n\n%s",lines[index]); //testing print


  }//variables are iterated here
}

再次感谢您的时间和帮助。

编辑:在下面回答

【问题讨论】:

  • 您的realloc() 电话使您的分配更小,而不是更大。
  • 如果你的尺寸总是200,那么realloc()ating 有什么意义?不是要重新分配给(previous size) + 200吗?您阅读realloc()的文档了吗?
  • realloc() 的大小参数是新的总大小,而不是大小的增量或减量。
  • 啊啊啊啊!!!谢谢,手册页有一个设置大小的增加,而不是增量增加!这太有道理了!!!请将您的评论作为答案,以便我标记为正确!
  • @ChristopherJordan “手册页有它可以增加设置的大小”——我简直不敢相信。您正在阅读哪个手册页,具体而言?您更可能误解了手册页的措辞。

标签: c realloc


【解决方案1】:

将评论转移到答案。

realloc() 的大小参数是新的总大小,而不是大小的增量或减量。 因此,当您重复调用 realloc(lines[index], 200) 时,您不会增加空间。

还要注意用法:

pointer = realloc(pointer, new_size);

是危险的,因为如果realloc() 失败,您已经丢失了指向之前分配的内存的指针,从而导致内存泄漏。虽然很冗长,但您应该使用:

void *new_space = realloc(pointer, new_size);
if (new_space == 0)
    …handle error…
pointer = new_space;

操作代码

请注意,我选择了INC_SIZEMAX_LINES 以便于测试(30 个字符比 200 个更容易;5 行比 12,000 个更容易)。另请注意,代码在成功读取数据后立即回显其输入;这有助于调试代码。它还将字符串括在尖括号中,以便更容易知道字符串的末端在哪里。这有时会揭示 Unix 机器上的 CRLF (DOS) 行尾等问题。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

enum { INC_SIZE = 30 };
enum { MAX_LINE = 5  };

int main(void)
{
    char *lines[MAX_LINE] = { 0 };
    int lineCount = 0;

    for (lineCount = 0; lineCount < MAX_LINE; lineCount++)
    {
        size_t lineSize = INC_SIZE;
        lines[lineCount] = malloc(lineSize * sizeof(char));
        if (lines[lineCount] == 0)
            break;
        if (fgets(lines[lineCount], INC_SIZE, stdin) == NULL)
            break;
        printf("In-1 <<%s>>\n", lines[lineCount]);
        char *temp = strchr(lines[lineCount], '\n');
        while (temp == NULL)
        {
            printf("string doesn't have have a newline character\n");
            size_t newSize = lineSize + INC_SIZE;
            void *newSpace = realloc(lines[lineCount], newSize);
            if (newSpace == NULL)
                break;
            lines[lineCount] = newSpace;
            lineSize = newSize;
            printf("added extra space\n");
            char temp2[INC_SIZE];
            if (fgets(temp2, INC_SIZE, stdin) == NULL)
                break;
            printf("In-2 <<%s>>\n", temp2);
            temp = strchr(temp2, '\n');
            strcat(lines[lineCount], temp2);
            printf("This is the line after cat: <<%s>>\n", lines[lineCount]);
        }
    }
    for (int i = 0; i < lineCount; i++)
        printf("Line: <<%s>>\n", lines[i]);
    for (int i = 0; i < lineCount; i++)
        free(lines[i]);
    return 0;
}

【讨论】:

  • 如果您可以再看一次我的代码,那将非常有帮助。我的 while 循环似乎在新行之前停止了 200。因此,如果它的长度为 1500 个字符,那么我的索引中将只有 1400 个字符。你看到有什么可能导致这种情况吗?我的逻辑似乎是正确的,当我在 while 循环中设置 temp 时,它应该得到所有内容,因为它不会取消直到新行?
猜你喜欢
  • 1970-01-01
  • 2016-10-09
  • 2018-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-28
  • 2013-02-17
相关资源
最近更新 更多