1. ホーム
  2. C language

free(): 次のサイズが無効 (fast): 0x0000000000aa4430 問題あり

2022-02-15 16:47:49

最近、タイトルのようなメッセージを表示するコードを書いていて、問題に遭遇しました: free(): invalid next size (fast): 0x0000000000aa4430.
生成されたコアファイルのbt情報を表示すると、以下のようになっています。
#0 0x00007f4910cb35f7 in raise () from /lib64/libc.so.6
#1 0x00007f4910cb4ce8 in abort () from /lib64/libc.so.6
#2 0x00007f4910cf3317 in __libc_message () from /lib64/libc.so.6
#3 0x00007f4910cfafe1 in _int_free () from /lib64/libc.so.6
推測では、freeするポインタが既に解放されているか、ポインタの指し示す内容が変更されていると思われます。他の可能性もあるので、この問題の他の可能性をWebで調べてみたところ
問題のコードを簡単に傍受してみると、おおよそ次のようなコードになっています。
char print_rpmpkg(char *pcpkgname)
{
int iRet = 0;
ssize_t read = 0;
size_t len = 0;
char *line=NULL。
FILE *fp= NULL。
char szCommand[128] = {0};
<スパン sprintf(szCommand, "rpm -ql %s", pcpkgname);
<スパン fp = popen(szCommand, "r");
if (fp == NULL)
errnoを返します。
<スパン line= (char *)malloc(sizeof(char)*BUF_LEN);
if (line == NULL)
{
iRet = -1;
goo out
}
printf("line ptr = %pn", line);
while((read=getline(&line,&len,fp))! =-1)
{
行[read-1] = 'ⅷ' です。
printf("%sn", line);
}
を出力します。
if (行)
{
printf("line ptr = %pn", line);
free(line)です。
line = NULLとする。
}
pclose(fp)です。
<スパン iRetを返します。
}
コードテストの結果、getline関数の後、ラインポインタが変更され、freeを実行してもfreeポインタが本来要求されたメモリ空間を指していないことがわかりました。解決策としては、中間ポインタ変数を定義し、中間変数にlineを代入し、中間変数を第1引数としてgetlineに渡せば問題なくなります。
char print_rpmpkg(char *pcpkgname)
{
int iRet = 0;
ssize_t read = 0;
size_t len = 0;
FILE *fp = NULL。
char *line = NULL。
char *pcBuf = NULL。
char szCommand[128] = {0};
<スパン sprintf(szCommand, "rpm -ql %s", pcpkgname);

<スパン fp = popen(szCommand, "r");
if (fp == NULL)
errnoを返します。
<スパン line= (char *)malloc(sizeof(char)*1024);
if (line == NULL)
{
iRet = -1;
goo out
}
printf("line ptr = %pn", line);
pcBuf = line;
while((read=getline(&pcBuf,&len,fp))! =-1)
{
pcBuf[read-1] = 'ⅷ' です。
printf("%sxxn", pcBuf);
}
を出力します。
if (行)
{
printf("line ptr = %pn", line);
free(line)です。
line = NULLとする。
}
pclose(fp)です。
<スパン iRetを返します。
}
結局この問題の原因はgetlineの問題で、ユーザーがgetlineの第1引数に渡すメモリ領域を自分で申請すると、第1引数を指すポインタを変更することになり、私の例のように使用すると、free(): invalid next size (fast): 0x0000000000aa4430 問題が発生することになるのです。
ネット上では、getlineを使用した際にこの問題が発生したブログをいくつか見かけましたので、getlineを使用する際は注意してください。
次に、free(): invalid next size (fast): 0x0000000000aa4430 という問題について、いくつかの可能性をウェブで調べてみました。
1. 解放されるオブジェクトが破損しており、他の場所で境界を越えて書き込まれた可能性があります。
2. 既に解放されたメモリポインタを解放する、または要求に成功していないメモリがないポインタを解放する。
3. 私の問題のように、解放されたポインタがmalloc中に返されたポインタではない、解放されたオブジェクトへのポインタが不正確である。