重新分配作业帮助

发布于 2024-10-31 01:14:21 字数 1521 浏览 4 评论 0原文

对于分配,我必须做的部分工作涉及使用 mallocrealloc。我首先创建一个二维字符数组,维度是行数和字符数。然后,我使用 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

For an assignment, part of what I have to do involves the use of malloc and realloc. I first create a 2D array of chars, the dimensions being the number of lines and the number of characters. I then use malloc to allocate enough memory to store input from some file. Using fgets I read one line in at a time, and store it in the array. This part works fine (or so I think). The problem comes in when I try to reallocate memory for more lines if need be. The program flow is supposed to be like this:

Create a character array of 50 lines, with 80 characters per line (working)

Use fgets to read one line at a time and save it to the array (working)

When 50 lines have been read, reallocate the array to allow for 100 lines (not working)

Keep reallocating as need be (not working)

This is what I have so far (the core of it at least, I omitted irrelevant code):

#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--;
}

My gut tells me the problem is with the realloc, so I'll explain what I think it's doing.

realloc(lines, (NUM_OF_LINES * reallocCount) * sizeof(*lines));

The first argument, lines, is the pointer I would like to reallocate a certain amount of memory. NUM_OF_LINES is the amount I would like to increase the size by. I multiply this by reallocLinesCount, which is a counter that keeps track of how many sets of 50 lines I ought to have. The sizeof(*lines) part is the size of a pointer to a char.

Thank you for reading and any help is greatly appreciated :)

EDIT: thank you all for the responses; I do not have time right now to read all of the answers right now, but all of your answers will be more thoroughly read and understood once this imminent deadline has passed :D

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

天涯沦落人 2024-11-07 01:14:21

我的座右铭是:“说出你的意思”。就您而言,您的意思是在数组不足以容纳数据时扩大数组。

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);
}

My motto is: "say what you mean". In your case, you MEAN to enlarge your array when it's not big enough to hold your data.

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);
}
空城旧梦 2024-11-07 01:14:21

realloc() 经常会发现没有足够的可用空间来就地扩展现有数组;在这种情况下,它将创建一个指定大小的全新数组,将旧数组的内容复制到新数组,释放旧数组,并返回指向新数组的指针。所以你应该这样写

char **oldLines = lines;
lines = realloc(...);

oldLines的目的是保留原始指针,以防realloc()耗尽内存并返回NULL,如下根据@Brian L 的提示)。

realloc() will often find out that there is not enough available room to expand the existing array in-place; in that case, it will create an entirely new array of the specified size, copy the contents of the old array to the new one, deallocate the old array, and return a pointer to the new one. So you should write

char **oldLines = lines;
lines = realloc(...);

(the purpose of oldLines is to keep the original pointer in case realloc() runs out of memory and returns NULL, as per @Brian L's tip).

爱情眠于流年 2024-11-07 01:14:21

这就是你应该如何重新分配:

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.
}

阅读重新分配参考了解详细信息。

编辑

您需要为每条新线分配更多分配。

This is how you should realloc:

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.
}

Read realloc reference for details.

EDIT

You need more allocation for each new lines.

逆光飞翔i 2024-11-07 01:14:21

您将更多的指针分配给行,而不是行本身。它位于代码的开头:

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

因此,在为每行分配行数后,您为该行本身分配空间。当您重新分配时,您忘记对新线路执行此操作。

You are allocating more pointers to lines but not the lines themselves. It is in your code at the beginning:

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

So after you allocated your number of lines for each line you allocate the space for the line itself. You forgot to do this for the new lines when you reallocate.

往事随风而去 2024-11-07 01:14:21

我们首先看看realloc()是如何工作的。它返回一个指向new的指针
成功时内存,失败时NULL。失败时,它不会
触摸旧内存,成功后,复制后就 free()
您的数据到新的地方。

所以,安全使用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))
从文件中读取行。

Let's first see how realloc() works. It returns a pointer to new
memory on success, and NULL on failure. On failure, it doesn't
touch the old memory, and on success, it free()'s it, after copying
your data to the new place.

So, the way to use realloc() safely is:

/* 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 */
}

So, the first thing is that you are using realloc() incorrectly.
You should never say x = realloc(x, ...);, because if realloc()
fails, you assign x to NULL, and the old memory is lost. This is
a memory leak.

Now, on to your problem. Let's say you have successfully read
NUMBER_OF_LINES lines. Now you want to make room for an additional
NUMBER_OF_LINES lines. You would do:

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);

One final note: it's almost always wrong to use while (!feof(fp))
to read lines from a file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文