#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 Это определенно больше используется. Тем более, что это решает всю возможную проблему «указателя на локальную переменную» на многих уровнях.