stdinから読み取る必要のあるプログラムをCで書いています。必要以上のメモリを割り当てたくないので、入力をチャンクでmalloc
読み取り、新しいチャンクが読み取られるたびにより多くのメモリを使用しています。
コードallocd
は次のとおりです(変数は、割り当てられたメモリの量を追跡するためだけのものです)。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZ 20
int main(int argc, char *argv[])
{
char *str = malloc(1), *p = NULL;
*str = '\0';
char buf[SIZ];
int bufs = 0;
int allocd = 0;
while (p = fgets(buf, sizeof(buf), stdin))
{
/* grow str */
str = realloc(str, bufs * SIZ + SIZ);
allocd = bufs * SIZ + SIZ;
strcat(str, buf);
bufs++;
if (!p)
break;
}
printf("ALLOC'D: %i", allocd);
free(str);
}
テスト用に、次のファイルfile.txt
を使用するとわかるように、966文字のファイルがありますwc
。
$ wc -m file.txt
966 file.txt
問題は、次のように、私のプログラムがファイル内の文字よりもはるかに多くのバイトのメモリを割り当てているように見えることです。
$ ./code <file.txt
ALLOC'D: 1680
なぜこれが起こっているのですか、どうすれば修正できますか?
実際の行の長さに関係なく、読み取った(試行した)行ごとに新しいメモリチャンクを割り当てます。私はfgets
ここで間違ったツールであると主張します、あなたが望むのはfread
代わりに:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZ 20
int main(int argc, char *argv[])
{
char *str = malloc(1);
*str = '\0';
char buf[SIZ];
int allocd = 0;
int p;
// Note: fread() returns size_t number of records read, NOT a char*
while ((p = fread(buf, 1, sizeof(buf), stdin)))
{
str = realloc(str, allocd + p + 1);
// Concatenate the buffer
memcpy(str + allocd, buf, p);
allocd += p;
}
str[allocd + 1] = 0;
printf("ALLOC'D: %i", allocd);
free(str);
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加