1

I'm trying to implement a brackets balance checker with stack, and I can't seem to shake off this

Error

tempCodeRunnerFile.c: In function ‘main’:
tempCodeRunnerFile.c:26:20: error: dereferencing pointer to incomplete type ‘struct StackRecord’
   26 |  S = malloc(sizeof(*S));
      |

 

Here's the code:

balance.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;
}

stack.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 */

I only put the important parts that cause the issue. It makes no sense since everything seems correct:/

3
  • 3
    If you want to create an opaque data structure, then you need to implement your own factory function for the creation of instances of the data structure. Commented Dec 15, 2020 at 19:30
  • You should read Modern C, the documentation of your C compiler (e.g. GCC...) and of your debugger (e.g. GDB). If you use GCC, compile with all warnings and debug info, e.g. gcc -Wall -Wextra -g. You could want to have some flexible array member Commented Dec 15, 2020 at 19:46
  • You might want to read some C standard, e.g. n2176. You surely want to take inspiration from existing open source software, for example GNU bash or remake or GTK. You could be interested by Frama-C Commented Dec 15, 2020 at 19:51

2 Answers 2

2

In the translation unit with main

#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;
}

the definition of the structure struct StackRecord is unknown. So the compiler is unable to calculate the size of an object of this type in the operator sizeof

S = malloc(sizeof(*S));

You need to move the structure definition from "stack.c" in the header "stack.h".

Pay attention to that according to the C Standard the function main shall be declared like

int main( void )

instead of

void main()
Sign up to request clarification or add additional context in comments.

Comments

0

In order to allocate a struct StackRecord, one needs to know the size of a struct StackRecord. And to know the size of a struct StackRecord using the sizeof operator, one needs the definition of a struct StackRecord.

The problem is that the definition of struct StackRecord is not found anywhere in the current translation unit. (stack.c is not involved in compiling balance.c.)

To solve this problem, move the definition of struct StackRecord from stack.c to stack.h, or have stack.c provide a function to allocate a struct StackRecord.

4 Comments

But shouldn't compiling like this: gcc balance.c stack.c fix the problem?
That's short for gcc -c balance.c; gcc -c stack.c; gcc balance.o stack.o It compiles balance.c, then compiles stack.c, then links the two .o files. The size is needed during compilation, not linking.
@DaviHlav You need to learn about the concept of translation units. The compiler doesn't see all source files, all it ever sees is a single translation unit (basically a single source file with all included header files). The compiler don't know anything about other translation units or what they contain. Even a command like gcc balance.c stack.c will build the two source files separately one by one.
@DaviHlav The code is not valid C, how you compile it doesn't change that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.