-1

C の記憶を更新しようとしています。テキスト ファイル内の HTML タグをチェックして、それらがすべて互いに一致していることを確認する簡単なプログラムがあります。これにはスタックを使用します。問題のコードは次のとおりです。

char *tag, *endTag;
stackADT stack = newStack();
while (!feof(input))
{
    tag = (char *)malloc(sizeof(char));
    tag = getNextTag(input, &line);
    printf("tag is %s\n", tag);     
    if (*(tag + 1) != '/') //if it is not a closing tag
    {
        push(stack, tag);
        printf("%s was pushed\n", tag);
    }
    else
    {
        endTag = (char *)malloc(sizeof(char));
        endTag = pop(stack);
        printf("%s was popped\n", endTag);
        check = doTagsMatch(endTag, tag);
        if (check == 0)
        {
            printf("Error at line %d: %s and %s do not match.\n", line, endTag, tag);
            exit(1);
        }
    }
    free(tag);
}

html、body、および p タグを含む単純なファイルからの出力は次のようになります。

tag is <html>
<html> was pushed
tag is <body>
<body> was pushed
tag is <p>
<p> was pushed
tag is </p>
 was popped
Error at line 1:  and </p> do not match.

いくつかの int を使用して別の SSCCE を実行し、正常に機能したため、スタック自体が正しく機能することはわかっています。私が endTag を使用するプログラム内の唯一の場所なので、pop から何も得られない理由がわかりません。私が考えることができる唯一のことは、それがどういうわけかポインタの問題であるということです(問題がある場合、私のスタック要素はvoid *です)。

4

2 に答える 2

1

tag各反復でfromを割り当てgetNextTag、後で を呼び出しますfree(tag)。を解放tagすると、それが指すメモリの内容は無効になります (C 標準では、それらを使用しようとした場合の動作が定義されていません)。

の定義を示していませんがpush、渡された値 ( ) を記録するだけで、何を指すtagかのコピーを作成していないと思われます。tagしたがって、 を呼び出すと、開始タグがプッシュされたときpopの値が返されますtagが、その値は無効になったメモリへのポインターです。

push渡された文字列のコピーを作成するかfree(tag)、値がスタックからポップされて不要になるまで呼び出されないようにする必要があります。(たとえば、elseタグをポップする句の最後で、 と の両方free(endTag)を呼び出します。ループの最後でfree(tag)呼び出さないでください。)free(tag)while

さらに、これらのシーケンスは無意味であり、メモリ リークが発生します。

tag = (char *)malloc(sizeof(char));
tag = getNextTag(input, &line);

endTag = (char *)malloc(sizeof(char));
endTag = pop(stack);

いずれの場合も、tagorendTagには から返された値が割り当てられますmallocが、その値はすぐに別の割り当てによって上書きされます。これは、によって返された値mallocが失われ、メモリは割り当てられたままですが、使用されないことを意味します。いずれの場合も、. を含む行を削除する必要がありmallocます。

于 2013-06-06T06:01:38.830 に答える