2017-03-02 83 views
0

我得到了下面的代码:的typedef不透明的指针,不透明的指针

// file external_module.h 
typedef externaldata * externalhdl; // opaque pointer 
externalhdl external_Create(); 

// file internal_module.h 
typedef internaldata * internalhdl; // opaque pointer 
internalhdl internal_Create(); 

我想什么做的是使用一个外部模块的不透明指针作为一个不透明的指针我的模块里面保存unessasary allocs 。目前我的解决办法执行力度是:

typedef struct {externalhdl e} internaldata; 

internalhdl internal_Create() 
{ 
    internalhdl p = (internaldata*) malloc (sizeof(internaldata)); 
    p.e = external_Create(); 
    return p; 
} 

我想这样做的是使用类似:

typedef ??? internaldata; //Don't know how 

internalhdl internal_Create() 
{ 
    return external_Create(); 
} 

从我的角度来看,这应该是可能的,因为两者都是指针,但我需要得到它警告免费?谢谢你的帮助。

+0

为什么不创建头文件,您可以在其中定义此结构,并将此文件包含到所有源代码中? – betontalpfa

+8

不,你这样做**不是**想要这样做!你根本不想'输入'一个opject指针!最清楚的是:**永远不会**'typedef'指向数据类型的指针!哦,'typedef'完全与内存分配有关。并提供[mcve]。你的代码结构和你的问题并不清楚。从你表现出来看起来好像你迷失在你的个人'typedef'地狱里。 – Olaf

+1

@betontalpfa:这不是_opaque_类型背后的想法。只是它不应该是'typedef'ed的指针。 – Olaf

回答

0

在我看来,你需要考虑的最重要的事情是,你将获得绝对的东西,但是在做这样的事情时会变得暗淡一些,并且你想要一个指向另一种类型的指针的指针。如果它是一个不透明的poitner,那么它对于typedef没有任何意义,因为你永远不会访问底层结构的成员,它很可能会作为void *指针传递,但是当你分配它时,你必须知道它是键入是因为编译器需要知道它的大小和布局以便正确分配它(例如,正确对齐,否则将不可能,否则)。

如果你不想重复使用sizeof运营商分配正确的尺寸有两种可能的方法

  1. 使用宏

    #define allocate(x) x = malloc(sizeof(*x)) 
    

    然后

    my_type *x; 
    allocate(x); 
    

    但这是h可怕和不清楚。

  2. 使用分配函数,

    my_type * 
    my_type_alloc() 
    { 
        return malloc(sizeof(my_type)); 
    } 
    

    这样

    my_type *x; 
    x = my_type_allocate(); 
    

    这是干净和简单,你不能这样做不对。

注意,返回相应的指针类型只是确保你不会不小心做一些事情,可能会导致不确定的行为,但分配函数可以简单地返回void *,他们将工作,这就是为什么我没有投malloc()“ s的回报值。

语法糖是一些你必须非常小心的事情,因为有时你看起来像简化和改进了语法,当你所做的事是从程序员那里读取你的代码的重要信息,程序员甚至可能是你自己编写代码后的一段时间。

而您的解决方法实际上正在导致一个不必要的分配。事实上,当你最终理解poitners时,你将会真正避免不必要的分配,因为当你只能从中读取数据时,不会复制数据。


在这两种情况下进行分配之后,以确保您可以访问这些指针,而不会导致不确定的行为

0

,你应该检查NULL这似乎你是在正确的轨道上在设计方面,这只是一个值得怀疑的实现。正如评论中所提到的,你不应该隐藏typedefs背后的指针,而opaque指针也不例外。如果来电者认为,这些都是分配的变量,他们可能会决定做愚蠢的事情是这样的:

set_obj(obj1, "foo"); // set private data to something 
memcpy(&obj2, &obj1); // take a hardcopy of the data (or so we thought) 
set_obj(obj1, "bar"); // set private data to something else 
print_obj(obj2);  // prints "bar", wtf!!! 

所以,不要隐藏指针。 稍作修改,你应该得到的代码按预期方式工作:

external.h

typedef struct external_t external_t; 

external_t* external_create (/* parameters here */); 

external.c

#include "external.h" 

external_t* external_create (/* parameters here */) 
{ 
    external_t* ext = malloc(sizeof *ext); 
    /* initialize stuff here */ 
    return ext; 
} 

internal.h

#include "external.h" 

typedef struct internal_t internal_t; 

internal_t* internal_create (/* parameters here */); 

内部.c

#include "internal.h" 

struct internal_t 
{ 
    external_t* ext; 
}; 

internal_t* internal_create (/* parameters here */) 
{ 
    internal_t* inter = malloc(sizeof *inter); 
    inter->ext = external_create (/* parameters here */); 
    if(inter->ext == NULL) 
    { 
    return NULL; 
    } 
    /* initialize stuff here */ 
    return inter; 
} 

调用者也必须使用指针。


此外,没有必要施放malloc的结果。击败这里的死马:
Do I cast the result of malloc?