我如何确定C结构中一个指针指针的元素数量

时间:2014-05-03 11:29:53

标签: c sizeof

我有以下C程序:

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

typedef struct node_t node_t;
    struct node_t
{
    char *name;
    node_t **nodes;
};

node_t* init(int p_n)
{
    node_t *node = malloc(sizeof(node_t));
    node->name = "_ROOT_";
    if(p_n > 0 && p_n < 10)
    {
        node->nodes = malloc(p_n*sizeof(node_t**));
        char nbuffer[9];
        int i;
        for(i = 0; i < p_n; i++)
        {
            node_t *child = malloc(sizeof(node_t));
            sprintf(nbuffer, "NAME %d", i);
            child->name = nbuffer;
            node->nodes[i] = child;
        }
    }
    return node;
}

int main(int argc, char *argv[])
{
    int n = 3;
    node_t *ROOT = init(n);
    printf("%sNODE {name:%s [%lu]}\n",
        "", ROOT->name, sizeof(ROOT->nodes)/sizeof(ROOT->nodes[0])
    );
    assert(n == sizeof(ROOT->nodes)/sizeof(ROOT->nodes[0]));
    free(ROOT);
    return 0;
}

主方法开头的断言失败,这是我的问题。我在评估成员节点的长度时遇到了什么问题?

我知道

This post,但由于某种原因,它对我不起作用。为什么呢?

SK

1 个答案:

答案 0 :(得分:0)

假设有32位指针。

sizeof(ROOT->节点)将是4个字节。指向指针的指针仍然是指针。

sizeof(ROOT->节点[0])也将是4个字节。它也是一个指针。

因此4/4!= 3并且您的断言失败。

我不确定你的目标是什么,但如果你想用动态分配的存储做这样的事情,你可能会做类似下面的事情。它可以通过其他API进行扩展,以添加,删除等。此解决方案可以维护列表中元素数量的计数。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#define NAME_SIZE 32

typedef struct node_s {
    char *name;
} node_t;

typedef struct node_list_s {
   int     count;
   node_t *nodes;
} node_list_t;

void init(node_list_t *l, int p_n) {
   int i = 0;
   char name[NAME_SIZE];

   if(!l) return;

   memset(l, 0, sizeof(node_list_t));
   l->nodes = malloc(p_n*sizeof(node_t));
   l->count = p_n;

   for(i=0;i<l->count;i++) {
      snprintf(name,sizeof(name),"NAME %d",i);
      l->nodes[i].name = strdup(name);
   }
}

void term(node_list_t *l) {
   int i = 0;
   if(!l) return;
   for(i=0;i<l->count;i++) {
      if(l->nodes[i].name) free(l->nodes[i].name);
   }
   if(l->nodes) free(l->nodes);
}

void print(node_list_t *l) {
   int i = 0;
   if(!l) return;
   for(i=0;i<l->count;i++) {
      printf("%d %s\n", i, l->nodes[i].name ? l->nodes[i].name : "empty" );
   }
}

int main(int argc, char *argv[]) {
    node_list_t list;

    init(&list, 3);
    print(&list);
    term(&list);
    return 0;
}