【问题标题】:C - Stack Implementation - malloc issueC - 堆栈实现 - malloc 问题
【发布时间】:2020-12-15 19:25:07
【问题描述】:

我正在尝试使用堆栈实现括号平衡检查器,但我似乎无法摆脱这个

错误

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

 

代码如下:

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

我只列出了导致问题的重要部分。这是没有意义的,因为一切似乎都是正确的:/

【问题讨论】:

  • 如果你想创建一个不透明的数据结构,那么你需要实现自己的工厂函数来创建数据结构的实例。
  • 您应该阅读 Modern C,您的 C 编译器(例如 GCC...)和调试器(例如 GDB)的文档。如果您使用 GCC,请使用所有警告和调试信息进行编译,例如gcc -Wall -Wextra -g。你可能想要一些flexible array member
  • 您可能想阅读一些 C 标准,例如n2176。您肯定想从现有 开源软件中汲取灵感,例如GNU bashremakeGTK。您可能对Frama-C 感兴趣

标签: c struct compiler-errors declaration definition


【解决方案1】:

在带有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;
}

结构struct StackRecord 的定义未知。所以编译器无法在sizeof运算符中计算出该类型对象的大小

S = malloc(sizeof(*S));

您需要将结构定义从"stack.c" 中的标题"stack.h" 中移动。

注意,根据 C 标准,函数 main 应声明为

int main( void )

而不是

void main()

【讨论】:

    【解决方案2】:

    为了分配struct StackRecord,需要知道struct StackRecord 的大小。要使用sizeof 运算符知道struct StackRecord 的大小,需要定义struct StackRecord

    问题是在当前翻译单元的任何地方都找不到struct StackRecord 的定义。 (stack.c 不参与编译balance.c。)

    为了解决这个问题,将struct StackRecord的定义从stack.c移动到stack.h,或者让stack.c提供一个分配struct StackRecord的函数。

    【讨论】:

    • 但不应该像这样编译:gcc balance.c stack.c 解决问题?
    • 这是gcc -c balance.c; gcc -c stack.c; gcc balance.o stack.o的缩写,它编译balance.c,然后编译stack.c,然后链接两个.o文件。编译时需要大小,而不是链接。
    • @DaviHlav 你需要了解translation units的概念。编译器不会看到所有源文件,它所看到的只是一个翻译单元(基本上是一个包含所有头文件的单个源文件)。编译器对其他翻译单元或它们包含的内容一无所知。即使像gcc balance.c stack.c这样的命令也会一个一个地分别构建两个源文件。
    • @DaviHlav 代码不是有效的 C,你如何编译它并没有改变。
    猜你喜欢
    • 2015-12-18
    • 2017-04-26
    • 2011-07-04
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    • 2011-10-31
    • 2010-10-22
    • 1970-01-01
    相关资源
    最近更新 更多