0

完全な開示:Cで重要なプログラミングを行うのはこれが初めてであり、StackOverflowに関する最初の投稿です。

私は、Scheme/Racket言語の小さなサブセットを実装するために最終的にBisonで使用されるコードに取り組んでいます。このコードはすべて単一のCファイルに含まれています。、、、の3つの構造体がBindingありLambdaますSymbolEntry。私はLambdaまだ構造体を使用していません、それは完全を期すためだけにあります。シンボルエントリを保持するシンボルテーブルもあります。printSymbolTable()名前が意味することを正確に実行します。

typedef struct
{
    char* name;
    char* value;
} Binding;

typedef struct
{
    int numBindings;
    Binding** bindings;
    char* functionBody; 
} Lambda;

typedef struct
{
    Binding* binding;
    Lambda* function;
} SymbolEntry;

SymbolEntry* symbolTable = NULL;
int numSymbols = 0;

void printSymbolTable()
{
    if (symbolTable)
    {
        int i = 0;
        for (i; i < numSymbols; i++)
        {
            printf("\tsymbolTable[%i]: %s = %s\n", i, symbolTable[i].binding->name, symbolTable[i].binding->value);
        }
    }
}

私は現在、変数を定義および検索するためのロジックを理解しようとしています。2つの関連する機能:

// Takes a name and an exprssion and stores the result in the symbol table
void defineVar(char* name, char* expr)
{
    printf("\nSetting %s = %s\n", name, expr);
    printf("Previous number of symbols: %i\n", numSymbols);
    Binding props;
    props.name = name;
    props.value = expr;

    SymbolEntry entry;
    entry.binding = &props;
    entry.function = NULL;

    symbolTable = realloc(symbolTable, sizeof(SymbolEntry) * ++numSymbols);
    if (!symbolTable)
    {
        printf("Memory allocation failed. Exiting.\n");
        exit(1);
    }
    symbolTable[numSymbols - 1] = entry;
    printf("New number of symbols: %i\n", numSymbols);
    printf("defineVar result:\n");
    printSymbolTable();
}

// Test storing and looking up at least 4 variables, including one that is undefined
void testVars()
{
    printf("Variable tests\n");

    defineVar("foo", "0");
    printf("After returning from defineVar:\n");
    printSymbolTable();

    defineVar("bar", "20");
    printf("After returning from defineVar:\n");
    printSymbolTable();
}

main()を呼び出しますtestVars()。コンパイル時に警告やエラーが発生せず、プログラムは正常に実行されます。ただし、これは結果です。

Variable tests

Setting foo = 0
Previous number of symbols: 0
New number of symbols: 1
defineVar result:
    symbolTable[0]: foo = 0
After returning from defineVar:
    symbolTable[0]: 1�I��^H��H���PTI��@ = �E

Setting bar = 20
Previous number of symbols: 1
New number of symbols: 2
defineVar result:
    symbolTable[0]: bar = 20
    symbolTable[1]: bar = 20
After returning from defineVar:
    symbolTable[0]: 1�I��^H��H���PTI��@ = �E
    symbolTable[1]: 1�I��^H��H���PTI��@ = �E���

関数の外部でジャンク値を取得するだけでなくdefineVar()、defineを呼び出すと、barジャンク以外の値が正しく表示されません。何が間違っているのかわかりませんが、おそらく。が付いているものだと思いrealloc()ます。ただし、文字列を個々のトークンに解析するときに同様の戦略が機能したため、それをエミュレートしようとしていました。私は何が間違っているのですか?

4

1 に答える 1

2

関数に対してローカルな変数 (または変数 — 少なくともprops、それ以上読んでいない) を指しているため、戻った後、スタック フレームは破棄されます (すぐに上書きされます)。

于 2012-11-03T22:15:20.993 に答える