C隐藏在结构中的数据:解释

时间:2014-06-22 10:25:52

标签: c encapsulation

我有这种情况:
我试图以这种方式模糊一些数据

/* item.h */
typedef struct ItemStruct *Item;

/*item.c*/
#include "item.h"

struct ItemStruct
{
    char word[MAXSTRING];
    int number;
};

Item ItemGet()
{
    Item i;

    i = (Item) malloc (sizeof(*i));
    if (i == NULL)
    {
        fprintf ( stderr, "Error: insufficient memory for new element.\n");
        return NULL;
    }

    return i;
}

好吧,我在朋友的解决方案中使用了这个malloc:

i = (Item) malloc (sizeof(*i));

但起初我写了这个:

i = (Item*) malloc (sizeof(Item));

这给了我一个"不完整的类型"每个' sizeof'我用于分配。
我问你为什么,因为我不明白这一点。

3 个答案:

答案 0 :(得分:2)

Item被定义为结构ItemStruct 的新类型指针。 sizeof(Item)将指向结构ItemStruct的指针大小,而不是其自身结构的大小。试试这个

i = malloc (sizeof(ItemStruct)); // or malloc (sizeof(*i))

关于投射,malloc会返回void *,并且可以将其指定给任何没有明确投射和never cast the return value of malloc的指针。

答案 1 :(得分:0)

您的Item是指针类型。您的sizeof(Item)返回该指针所需的字节数。那不是你想要分配的内存量。您希望分配足够的内存来存储指向的结构。并且你将结果转换为指向指针类型的指针,这没什么意义。

每次你有类似的东西:

T* myPointer;

您必须将内存分配为:

myPointer = (T*)malloc(num_of_Ts * sizeof(T));

相当于:

myPointer = (T*)malloc(num_of_Ts * sizeof *myPointer);

在您的情况下,Item是您的T *,并且您只想分配1个结构:

i = (Item)malloc(sizeof(ItemStruct));

相当于:

i = (Item)malloc(sizeof *i);

请注意,您不需要在C中强制使用malloc的结果(这样做是不好的做法),而您必须在C ++中这样做。

答案 2 :(得分:0)

将模块接口中可见的对象声明为不完整的结构,或者将其定义为指向不完整结构的指针是信息隐藏的可行方法。当没有结构元素定义的代码试图做一些需要知道该结构大小的事情时,你应该得到关于不完整类型的错误。 (声明最常见的变量)。这种类型的代码中的一个常见错误是,在typedef中使用结构标记的名称与使用它来声明实际结构之间的结构标记名称不同,这通常会导致实现代码中不完整类型的错误错误。

接下来是两组代码。文件pitem.c pitem.h和pmain.c在gcc下用-Wall编译,没有使用指针方法的警告。使用不完整的结构方法,文件item.c item.h和main.c编译类似。

就个人而言,我更喜欢不完整的结构方法。接口的用户知道他们正在处理这种方法中的指针。它们具有额外的灵活性,可以将其初始化为NULL,如main.c中所示。这种方法的偏好(与隐藏界面可见对象是指针的事实相反)可能是tristopia的评论所指的。

pitem.h

typedef struct ItemStruct *Item;

Item ItemGet();

pitem.c

#include "pitem.h"
#include <stdio.h>
#include <stdlib.h>


#define MAXSTRING 32


struct ItemStruct
{
    char word[MAXSTRING];
    int number;
};

Item ItemGet()
{
    Item i;

    i = (Item) malloc (sizeof(*i));
    if (i == NULL)
    {
        fprintf ( stderr, "Error: insufficient memory for new element.\n");
        return NULL;
    }

    return i;
}

pmain.c

#include "pitem.h"


int main(int argc , char **argv)
{
  Item  item;

  (void) argc;  /* not being used*/
  (void) argv;  /* not beign used*/

  item = ItemGet();
  (void)item;  /* not being used */

  return(0);

}

item.h

typedef struct ItemStruct Item;

Item *ItemGet();

item.c

#include "item.h"
#include <stdio.h>
#include <stdlib.h>


#define MAXSTRING 32


struct ItemStruct
{
    char word[MAXSTRING];
    int number;
};

Item *ItemGet()
{
    Item *i;

    i = (Item *) malloc (sizeof(*i));
    if (i == NULL)
    {
        fprintf ( stderr, "Error: insufficient memory for new element.\n");
        return NULL;
    }

    return i;
}

的main.c

#include "item.h"
#include <stdlib.h>

int main(int argc , char **argv)
{
  Item  *pItem=NULL;

  (void) argc;  /* not being used*/
  (void) argv;  /* not beign used*/

  pItem = ItemGet();
  (void)pItem;  /* not being used */

  return(0);

}