#c #struct #compiler-errors #declaration #definition
#c #структура #ошибки компилятора #объявление #определение
Вопрос:
Я пытаюсь реализовать проверку баланса скобок с помощью stack, и, похоже, я не могу избавиться от этого
Ошибка
tempCodeRunnerFile.c: In function ‘main’:
tempCodeRunnerFile.c:26:20: error: dereferencing pointer to incomplete type ‘struct StackRecord’
26 | S = malloc(sizeof(*S));
|
Вот код:
баланс.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "stack.h"
void main()
{
struct StackRecord *S;
char str[500], c;
int l, i;
S = malloc(sizeof(*S));
while (1) {
.............
.............
return;
}
стек.c
#include "stack.h"
#include "fatal.h"
#include <stdlib.h>
#define EmptyTOS ( -1 )
#define MinStackSize ( 5 )
struct StackRecord
{
int Capacity;
int TopOfStack;
ElementType *Array;
};
.............
.............
stack.h
typedef int ElementType;
/* START: fig3_45.txt */
#ifndef _Stack_h
#define _Stack_h
struct StackRecord;
typedef struct StackRecord *Stack;
int IsEmpty( Stack S );
int IsFull( Stack S );
Stack CreateStack( int MaxElements );
void DisposeStack( Stack S );
void MakeEmpty( Stack S );
void Push( ElementType X, Stack S );
ElementType Top( Stack S );
void Pop( Stack S );
ElementType TopAndPop( Stack S );
#endif /* _Stack_h */
/* END */
Я помещаю только важные части, которые вызывают проблему. Это не имеет никакого смысла, так как все кажется правильным:/
Комментарии:
1. Если вы хотите создать непрозрачную структуру данных, то вам необходимо реализовать собственную фабричную функцию для создания экземпляров структуры данных.
2. Вы должны прочитать Modern C , документацию вашего компилятора C (например, GCC …) и вашего отладчика (например, GDB ). Если вы используете GCC, скомпилируйте со всеми предупреждениями и отладочной информацией, например
gcc -Wall -Wextra -g
. Возможно, вам захочется иметь какой-то гибкий элемент массива3. Возможно, вам захочется прочитать какой-нибудь стандарт C, например, n2176 . Вы наверняка хотите черпать вдохновение из существующего программного обеспечения с открытым исходным кодом, например GNU bash или remake или GTK . Вас может заинтересовать Frama-C
Ответ №1:
В блоке перевода с основным
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "stack.h"
void main()
{
struct StackRecord *S;
char str[500], c;
int l, i;
S = malloc(sizeof(*S));
while (1) {
.............
.............
return;
}
определение структуры struct StackRecord
неизвестно. Таким образом, компилятор не может вычислить размер объекта этого типа в операторе sizeof
S = malloc(sizeof(*S));
Вам необходимо переместить определение структуры из "stack.c"
заголовка "stack.h"
.
Обратите внимание на то, что в соответствии со стандартом C функция main должна быть объявлена как
int main( void )
вместо
void main()
Ответ №2:
Чтобы выделить a struct StackRecord
, нужно знать размер a struct StackRecord
. И чтобы узнать размер a struct StackRecord
с помощью sizeof
оператора, нужно определение a struct StackRecord
.
Проблема в том, что определение struct StackRecord
нигде не найдено в текущей единице перевода. ( stack.c
не участвует в компиляции balance.c
.)
Чтобы решить эту проблему, переместите определение struct StackRecord
from stack.c
в stack.h
, или stack.c
предоставьте функцию для выделения struct StackRecord
.
Комментарии:
1. Но разве не следует компилировать так:
gcc balance.c stack.c
исправить проблему?2. Это сокращение
gcc -c balance.c; gcc -c stack.c; gcc balance.o stack.o
от того, что он компилирует balance.c, затем компилирует stack.c, а затем связывает два файла .o. Размер необходим во время компиляции, а не связывания.3. @DaviHlav Вам нужно узнать о концепции единиц перевода . Компилятор не видит все исходные файлы, все, что он когда-либо видит, — это одна единица перевода (в основном один исходный файл со всеми включенными файлами заголовков). Компилятор ничего не знает о других единицах перевода или о том, что они содержат. Даже такая команда, как
gcc balance.c stack.c
будет создавать два исходных файла отдельно один за другим.4. @DaviHlav Код не является допустимым C, то, как вы его компилируете, этого не меняет.