Удержание указателей на структуры внутри одной и той же структуры (C)

#c

Вопрос:

В настоящее время я пишу небольшой компилятор на C и сталкиваюсь со странной проблемой, которая, похоже, связана с тем, как я храню указатели на структуры в массиве внутри одной и той же структуры. У меня есть таблица символов структуры, которая выглядит так:

 typedef struct SymbolTable_t
{
    // testing
    int id;

    Symbol symbols[40];
    int count;
    struct SymbolTable_t * parent;

    int scopeCount;
    struct SymbolTable_t * childScopes[40];
} SymbolTable;
 

И когда я хочу создать новую таблицу символов, я передаю указатель на ее родителя в качестве аргумента, и родитель также получает указатель на этот новый дочерний элемент, добавленный в его массив дочерних областей, например:

 SymbolTable createSymbolTable(SymbolTable* parent)
{
    //if(parent->scopeCount == 1) printf("%dn", parent->childScopes[0]->id);

    SymbolTable t;
    t.count = 0;
    t.scopeCount = 0;
    t.parent = parent;

    memset(t.symbols, 0, 40*sizeof(Symbol));
    for(int i = 0; i < 40; i  )
    {
        t.childScopes[i] = (SymbolTable *)malloc(sizeof(SymbolTable));
    }

    if(parent != NULL)
    { 
        addChildScope(parent, amp;t);
    }

    return t;
}

void addChildScope(SymbolTable* parent, SymbolTable* child)
{
    parent->childScopes[parent->scopeCount] = child;
    parent->scopeCount  ;
}
 

Мне кажется, что это простая система, которая должна работать, однако иногда, когда я создаю новую таблицу символов, которая разделяет родительский элемент с другим, данные в этой более старой таблице символов перезаписываются, как будто массив дочерних областей не обновляется должным образом? Я думаю, что сузил проблему до этих небольших функций, поэтому я предположил, что у меня какое-то переполнение стека или что-то в этом роде, но я не смог найти проблему с кодом.

NB: Если я раскомментирую первую строку createSymbolTable, я получу segfault, хотя, очевидно, этого делать не следует, так как если scopeCount равен 1, то первый элемент дочерних областей должен содержать таблицу символов. (Я знаю, что идентификатор будет мусором, я просто пытаюсь проверить детские области с помощью этого теста)

Я действительно не уверен в том, что является причиной этого, любая помощь была бы очень признательна. Ваше здоровье.

Комментарии:

1. Если вы получаете segfault, то один из ваших указателей неверен. Segfault уже должен был дать вам этот намек.

2. […] новая таблица символов, которая разделяет родительский элемент с другим […] Я думаю, что код, вызывающий проблему, не отображается. Вероятно, вы освободите родителя до того, как все дети будут освобождены.

3. Я удалил все свои бесплатные звонки в других местах программы для тестирования, так как я думал, что это может быть хорошо, но это не исправило ситуацию.

Ответ №1:

Проблема в звонке

 addChildScope(parent, amp;t);
 

Здесь вы передаете указатель на локальную переменную t . И поскольку все локальные переменные его срок службы заканчивается с окончанием функции, в которой он определен (т. Е. Он перестает существовать после createSymbolTable возврата), оставляя вас с недопустимым указателем.

Чтобы создать новую структуру, вам необходимо динамически распределить ее с помощью malloc .

Комментарии:

1. Хорошо, это имеет большой смысл, и действительно решило мою проблему. Большое спасибо.

2. @JamesMclaughlin Не забудьте вернуть указатель, а не объект структуры.

3. Да, я изменил функцию, чтобы сделать это вместо этого. Будет ли это более стандартной практикой в C, возвращающей указатель на структуру, а не на саму структуру?

4. @JamesMclaughlin Это определенно больше используется. Тем более, что это решает всю возможную проблему «указателя на локальную переменную» на многих уровнях.