0

以下のプログラムは、入力a sentencean old word、およびを受け取りますnew word
目的はreplace all the occurrences old word with the new wordです。

int countOccurrence(char* sen,char* word) //counts occurrences of old word
{
    int count=0,i,k,len1,len2;

    len1=strlen(sen);
    len2=strlen(word);
    for(i=0;i<len1-len2+1;)
    {
            k=0;
            while(word[k] && sen[k+i]==word[k])
                    k++;
            if(k==len2 && sen[k+i]==' ' || sen[k+i]=='\0')
            {
                    count++;
                    i+=len2;
            }
            else ++i;
    }
    return count;
}

void replace(char* sen,char* oldword,char* newword)
{
    int count,len1,len2,len3,i,top=-1,k;
    char *ptr;

    count=countOccurrence(sen,oldword);

    if(!count) return;

    len1=strlen(sen);
    len2=strlen(oldword);
    len3=strlen(newword);

    ptr=(char*)malloc(sizeof(len1+count*(len3-len2)+1));

    for(i=0;i<len1-len2+1;)
    {
            k=0;
            while(oldword[k] && sen[k+i]==oldword[k])
                    k++;
            if(k==len2 && sen[k+i]==' ' || sen[k+i]=='\0')
            {
                    for(k=0;newword[k];++k)
                            ptr[++top]=newword[k];
                    i+=len2;
            }
            else
            {
                    ptr[++top]=sen[i];
                    ++i;
            }
    }       
    ptr[++top]='\0';

    strcpy(sen,ptr);

    free(ptr); <-------------------------------
} 

実行後、次のようなエラーが表示されます: http://ideone.com/mh3X1

*** glibc detected *** ./prog: free(): invalid next size (fast): 0x08f49008 ***
======= Backtrace: =========
/lib/libc.so.6[0xb75fcfd4]
/lib/libc.so.6(cfree+0x9c)[0xb75fe87c]
./prog[0x8048834]
./prog[0x80484c1]
======= Memory map: ========    

ステートメントにコメントすると、プログラムは機能します。

free(ptr);    

こちらをご覧ください: http://ideone.com/fr34H

ヒープに割り当てられたメモリを free() しようとするとエラーが発生するのはなぜですか?

4

3 に答える 3

5

で保持されている内部情報を台無しにしmallocて、次の操作時にそれを検出しました (これは無料でした)。理由は次のとおりです。

ptr=(char*)malloc(sizeof(len1+count*(len3-len2)+1));
                  ^^^^^^

このコンテキストでは、 sizeof は、プラットフォームの整数のサイズに評価されます。ほぼ確実に、必要なものよりも小さくなります。したがって、 に書き込むとptr、4 または 8 バイトの後に、割り当てられた領域の外に出て、すべての賭けがオフになります。


補足: これは主に好みの問題ですが、 によって返される値のキャストを停止する必要がありますmalloc

于 2012-07-26T13:47:23.343 に答える
4

この行は疑わしいです:

ptr=(char*)malloc(sizeof(len1+count*(len3-len2)+1));

あなたはそこにいたくsizeofありません。

于 2012-07-26T13:47:33.257 に答える
1

これは、ヒープ破損の典型的なケースです。プログラムのどこかで、動的配列の境界の外に書き込んでおり、free何をすべきかを理解するために必要なデータを上書きしています。

valgrindを実行してみてください:

valgrind --leak-check=full ./your_program

他の人が述べたように、メモリを適切に割り当てていませんptr。私が見ることができる別の問題はstrcpy(sen,ptr);. 最終結果のサイズは文よりも大きくなる可能性があるため、境界も超えてしまいますsen

于 2012-07-26T13:45:58.663 に答える