realloc作业帮助

对于作业,我必须做的部分工作涉及使用
malloc
realloc
。我首先创建一个字符的二维数组,维度是行数和字符数。然后我使用
malloc
分配足够的内存来存储来自某个文件的输入。使用
fgets
我一次读入一行,并将其存储在数组中。这部分工作正常(或者我认为)。当我尝试在需要时为更多行重新分配内存时,会出现问题。程序流应该是这样的: 创建一个50行的字符数组,每行80个字符(工作) 使用
fgets
一次读取一行并将其保存到阵列(工作) 当读取50行时,重新分配数组以允许100行(不工作) 根据需要保持重新分配(不工作) 这是我到目前为止(至少它的核心,我省略了不相关的代码):
#define NUMBER_OF_LINES 50
#define CHARACTERS_PER_LINE 80

FILE *inputFile = fopen("some.text", "r");

char **lines;
lines = malloc(NUMBER_OF_LINES * sizeof(*lines));
int i;
for (i = 0; i < NUMBER_OF_LINES; i++)
  *(lines+i) = malloc(CHARACTERS_PER_LINE * sizeof(char));

int linesRemaining = NUMBER_OF_LINES;
int reallocCount = 1;
i = 0;
while (!feof(inputFile)) {
  if (!linesRemaining) {
    reallocCount++;
    lines = realloc(lines, (NUM_OF_LINES * reallocCount) * sizeof(*lines));
    linesRemaining = NUM_OF_LINES;
  }
  fgets(*(lines+i), CHARS_PER_LINE, inputFile);
  i++;
  linesRemaining--;
}
我的直觉告诉我问题是
realloc
,所以我会解释我认为它在做什么。
realloc(lines, (NUM_OF_LINES * reallocCount) * sizeof(*lines));
第一个参数
lines
是我想重新分配一定量内存的指针。
NUM_OF_LINES
是我希望增加大小的数量。我乘以
reallocLinesCount
,这是一个计数器,记录我应该有多少50行。
sizeof(*lines)
部分是指向
char
的指针的大小。 感谢您阅读,非常感谢任何帮助:) 编辑:谢谢大家的回复;我现在没有时间阅读所有答案,但是一旦即将到来的截止日期已经过去,您的所有答案都将得到更全面的阅读和理解:D     
已邀请:
我的座右铭是:“说出你的意思”。在您的情况下,当您的阵列不足以保存数据时,您可能会扩大阵列。
FILE *in;      // you fill this in
int nlines=50; // initial value
char **buffer=malloc(nlines * sizeof *buffer);
int i=0;

for(int i=0; !feof(in); ++i)
{
  if(i>=nlines)
    buffer=realloc(buffer, (nlines+=50)*sizeof *buffer);

  buffer[i]=malloc(80);
  fgets(buffer[i], 80, in);
}
    
realloc()
经常会发现没有足够的空间来扩展现有阵列;在这种情况下,它将创建一个指定大小的全新数组,将旧数组的内容复制到新数组,取消分配旧数组,并返回指向新数组的指针。所以你应该写
char **oldLines = lines;
lines = realloc(...);
oldLines
的目的是保留原始指针,以防
realloc()
内存耗尽并返回
NULL
,按照@Brian L'的提示)。     
这是你应该重新分配的方式:
char **new_lines = realloc(lines, (NUM_OF_LINES * ++reallocLinesCount) * sizeof(*lines));
if (new_lines)
{
    lines = new_lines;
}
else
{
    // Memory allocation fails. Do some error handling.
}
阅读realloc参考了解详细信息。 编辑 每个新行需要更多分配。     
您正在为线分配更多指针,而不是线本身。它在您的代码开头:
for (i = 0; i < NUMBER_OF_LINES; i++)
   *(lines+i) = malloc(CHARACTERS_PER_LINE * sizeof(char));
因此,在为每行分配行数后,您将为行本身分配空间。重新分配时,您忘记为新行执行此操作。     
我们先来看看
realloc()
是如何工作的。它返回一个指向new的指针 记忆成功,
NULL
失败。失败时,它没有 触摸旧记忆,成功之后,复制之后就是它 你的数据到了新的地方。 因此,安全使用
realloc()
的方法是:
/* allocate memory using malloc() */
ptr = malloc(N * sizeof *ptr);
/* make sure malloc succeeded */
...
/* call realloc() */
new_ptr = realloc(ptr, M * sizeof *new_ptr);
/* see if it succeeded */
if (new_ptr) {
    /* okay, we can set ptr */
    ptr = new_ptr;
} else {
    /* realloc failed, old pointer still valid */
}
所以,首先是你错误地使用
realloc()
。 你永远不应该说
x = realloc(x, ...);
,因为如果
realloc()
失败,你将
x
分配给
NULL
,旧的内存丢失。这是 内存泄漏。 现在,关于你的问题。假设您已成功阅读
NUMBER_OF_LINES
线。现在你想为额外的空间腾出空间
NUMBER_OF_LINES
线。你会这样做:
char **new_lines = realloc(lines, NUMBER_OF_LINES*reallocCount*sizeof *new_lines);
if (new_lines) {
    lines = new_lines;
} else {
    fprintf(stderr, "realloc failed!n");
    return;
}

/* Now, lines[NUMBER_OF_LINES] to lines[2*NUMBER_OF_LINES-1] are
 * available to point someplace useful.  They don't point anywhere
 * useful yet.  We have to allocate memory for them, just like earlier */

start = NUMBER_OF_LINES*reallocCount;
for (i=0; i < NUMBER_OF_LINES; ++i) {
    /* You weren't allocating memory here, and were writing to
     * lines[0] through lines[NUMBER_OF_LINES-1], which is not what
     * you want. */
    lines[start+i] = malloc(CHARS_PER_LINE * sizeof *lines[start+i]);
    /* check the result of malloc here */
}
fgets(lines[start+i], CHARS_PER_LINE, inputFile);
最后一点说明:使用
while (!feof(fp))
几乎总是错误的 从文件中读取行。     

要回复问题请先登录注册