C-将“组合/继承”结构实例传递给其基本类型的指针

时间:2018-11-13 08:05:19

标签: c struct valgrind

所以,我有2个结构。

第一个:

typedef struct AST_NODE_STRUCT {
    token* tok;
} ast_node;

另一个:

typedef struct AST_BINOP_STRUCT {
    ast_node base;

    token* tok;

    ast_node* left;
    ast_node* right;
} ast_node_binop;

现在,我有一个看起来像这样的方法:

void do_something(ast_node* node) {
    ...
}

我想传入ast_node_binop结构的实例... 如果将ast_node_binop强制转换为ast_node,则不会引发编译错误,但valgrind会说:

==6554== Memcheck, a memory error detector
==6554== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==6554== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==6554== Command: ./cola.out examples/hello_world.cola
==6554== 
==6554== Stack overflow in thread #1: can't grow stack to 0xffe801000
==6554== 
==6554== Process terminating with default action of signal 11 (SIGSEGV)
==6554==  Access not within mapped region at address 0xFFE801FE8
==6554== Stack overflow in thread #1: can't grow stack to 0xffe801000
==6554==    at 0x109B20: parse_expr (parse.c:88)
==6554==  If you believe this happened as a result of a stack
==6554==  overflow in your program's main thread (unlikely but
==6554==  possible), you can try to increase the size of the
==6554==  main thread stack using the --main-stacksize= flag.
==6554==  The main thread stack size used in this run was 8388608.
==6554== Stack overflow in thread #1: can't grow stack to 0xffe801000
==6554== 
==6554== Process terminating with default action of signal 11 (SIGSEGV)
==6554==  Access not within mapped region at address 0xFFE801FD8
==6554== Stack overflow in thread #1: can't grow stack to 0xffe801000
==6554==    at 0x4A266B0: _vgnU_freeres (vg_preloaded.c:59)
==6554==  If you believe this happened as a result of a stack
==6554==  overflow in your program's main thread (unlikely but
==6554==  possible), you can try to increase the size of the
==6554==  main thread stack using the --main-stacksize= flag.
==6554==  The main thread stack size used in this run was 8388608.
==6554== 
==6554== HEAP SUMMARY:
==6554==     in use at exit: 4,587 bytes in 6 blocks
==6554==   total heap usage: 16 allocs, 10 frees, 9,281 bytes allocated
==6554== 
==6554== LEAK SUMMARY:
==6554==    definitely lost: 0 bytes in 0 blocks
==6554==    indirectly lost: 0 bytes in 0 blocks
==6554==      possibly lost: 0 bytes in 0 blocks
==6554==    still reachable: 4,587 bytes in 6 blocks
==6554==         suppressed: 0 bytes in 0 blocks

我查看了这篇stackoverflow帖子:Struct Inheritance in C,以了解如何在C中实现“结构”继承。

我基本上只是希望能够将从另一个结构派生的结构实例传递给需要基本/父结构的函数。

正确的方法是什么? 我将从ast_node中获得多个“派生”结构,而我将不总是知道它是哪个派生结构,我只是知道它们将始终源自ast_node其中:ast_node base;在结构中。

我知道它令人困惑,但是希望您能理解我正在努力实现的目标。

这里是parse.c,因为评论中的人说valgrind抱怨其他问题:https://pastebin.com/SvqeHKqs

1 个答案:

答案 0 :(得分:0)

这是正确的方法。所发布的错误与继承或类型转换无关,而是某种完全不相关的堆栈溢出方式。也许您正在使用递归之类的功能-我不知道。

ast_node_binop*强制转换为ast_node*,然后让该函数访问ast_node_binop内部的数据是非常好的定义。

从形式上讲,这由C17 6.5§7保证,ast_node_binop是一个聚合,在其成员中包括左值类型ast_node。它是该结构的第一个成员,因此有关填充和对齐的问题也不适用。