【发布时间】:2015-09-04 11:49:40
【问题描述】:
我是 C 新手,这是我的第一个问题: 对于这个结构:
typedef struct Branch
{
Tree * thisTree;
struct Branch * nodes[];
} Branch;
如果我执行以下操作,它似乎可以正常工作:
Branch branch1;
branch1->nodes[0] = NULL;
即使我没有以这种方式为数组中的指针 nr 0 分配内存:
branch->node[0] = (Branch *) malloc(sizeof(Branch *));
如果我检查此代码:
if ( branch1->nodes[0] == NULL)
printf("is NULL");
它打印到输出:是NULL
所以我的问题是: 是否为指针分配了内存?
branch1->nodes[0]
因为我有很多结构,如果我用固定数量的指针初始化每个分支,我会得到很多分配的数据(如果我检查 sizeof 函数)。 这种方式:设置为NULL(上图)是一种错误的思维方式吗?
我的问题是指针的内存分配是 4 个字节。所以在数组中没有声明数量的指针,它什么时候为它分配内存? 对不起 我试图让问题保持简单,但我需要通过下一个分支中的结构指针到达一个字符串
这意味着我使用的结构是
typedef struct Branch
{
Tree * thisTree;
char *string;
struct Branch * nodes[];
} Branch;
如果我不这样做
branch->node[0] = (Branch *) malloc(sizeof(Branch *));
比
branch->node[0]->String = strdup("text");
我遇到编译器错误。
【问题讨论】:
-
不要将
malloc和朋友的结果投射到C中。 -
你做到了。 C 不是 Java 或 Python 等。指针不是引用,而是一等对象。使用 valgrind。如果你不这样做,一个简单的比较甚至可能会起作用,你不能依赖 undefined behavior not 来产生正确的结果。
-
@user3079666:阅读standard。强制转换禁止编译器进行类型检查。如果您的返回类型或参数类型与预期不同,编译器不会警告您。因此,仅在需要时使用强制转换,并且您真的知道自己在做什么。
-
@BlindWhiteLabMouse 你需要非常小心你在这里做什么。你的
struct Branch * nodes[];很特别,叫做flexible array member。您还没有为此分配任何内存,所以branch1->nodes[0]是未定义的行为。 -
@Olaf C++ 解决了 C 中的一些缺陷,其中包括过于宽松的类型系统。某些被视为危险的隐式转换被禁止,其中包括从 void* 到其他指针的转换。我认为推理有效。我通常也会尝试让我的 C 程序成为 C++ 程序。我知道针对该特定演员的反驳论点,但发现它们要么无效,要么认为它们没有超过好处。我爱我的编译器。如果我在没有先声明的情况下使用函数(如 malloc),它会警告我(任何理智的语言首先都不会允许这种危险,另一课)。