Sign up ×
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other. Join them, it only takes a minute:

So I have a program I am working on to implement a B-Tree, but I am getting a few annoying compiling errors. The B-Tree structure was working, but I have to implement a functionality to accept the order of the tree as an input, which is causing some problems. The errors I have are:

Prelim.c:29:38: error: expected ‘:’, ‘,’, ‘;’, ‘}’ or ‘attribute’ before ‘=’ token

Prelim.c:26:6: error: flexible array member not at end of struct

The code affected is:

struct bTreeNode {                      
    int count;                      
    int value[];                                   // This is line 26

    struct bTreeNode *branch[]; 

    struct bTreeNode *branch[order - 1] = malloc(sizeof(order));   // This is line 29
    int value[order - 1] = malloc(sizeof(order));

};

My question is two parts: First, why are these errors occurring, and second, How can I implement this idea properly? (I can provide additional code if needed and order is declared as a global variable). Thanks so much for your help!

share|improve this question
1  
You can't allocate structure in structure definition. Also allocation syntax which you have used is totally wrong. learn how to use malloc for dynamically allocate structures. – Jayesh Sep 10 '14 at 4:40

3 Answers 3

  1. "why are these errors occurring"

    In your code, branch is an array of bTreeNode pointers, so you must tell compiler the length of branch. try this code:

    #define ORDER 10; // hard-coded
    struct bTreeNode {
        int count;
        int value[ORDER];
        struct bTreeNode *branch[ORDER - 1]; 
        int value[ORDER - 1];
    };
    

    And you can not use any functions in struct bTreeNode definition.

  2. " How can I implement this idea properly"

    Flexible array is a good idea, try struct bTreeNode *branch[0], and allocate memory later. Sorry for my ugly english. ^_^

share|improve this answer
    
Flexible array members do not need to be declared as [0] but just as [] but they should be the last member of the struct (and the only flexible one). – Basile Starynkevitch Sep 10 '14 at 5:20
    
Disagree, if flexible array is declared as [], MinGW would tell you "error: flexible array member in otherwise empty struct". However, [0] has compatibility. – Anthony Cooper Sep 10 '14 at 5:30
    
Flexible array are C99 only – Basile Starynkevitch Sep 10 '14 at 5:33
    
Disagree again, I haven't seen any sentences like "obsolete flexible array" or "deprecate flexible array " in C11 standard. – Anthony Cooper Sep 10 '14 at 6:19
    
I just meant that they are not (yet) in the old C89 or ANSI-C standard. – Basile Starynkevitch Sep 10 '14 at 6:58

this declaration has a problem

struct bTreeNode *branch[order - 1] = malloc(sizeof(order));

the branch pointer is suppose to point at (order - 1) b-tree nodes, but you are allocating the memory size of order (which is probably an int, so it will return 4 bytes probably) you need to allocate the memory of btreeNode times the order (number of btree nodes * order). try this..

struct bTreeNode *branch = malloc(sizeof(struct bTreeNode)*order);
share|improve this answer

You are having a flexible array member, that is inside a struct an array without dimensions known at compile time. You can only have one of them, and it should be the last member of the struct:

struct bTreeNode {                      
  int count;                      
  int value[];     // flexible array member
};

flexible array members is an advanced feature of C99

I'm guessing that you want your node to have arbitrary number of values and arbitrary number of sons. You need two flexible struct for that and you should use pointers.

// forward declarations
struct bTreeNode;
struct bTreeNumber;
struct bTreeSons;

struct bTreeNumber {
  unsigned valcount;
  int value[]; // actual dimension is valcount
};

struct bTreeSons {
   unsigned soncount;
   struct bTreeNode* ptrs[]; // actual dimension is soncount
};

struct bTreeNode {
  struct bTreeNumbers* numbers;
  struct bTreeSons* sons; 
};

Here is a function allocating an empty node with a given number of values and another number of sons

struct bTreeNode *make_node (unsigned nbval, unsigned nbsons)
{
   struct bTreeNumber* pnum = 
      malloc(sizeof(bTreeNumber)+nbval*sizeof(int));
   if (!pnum) { perror("malloc bTreeNumber"); exit(EXIT_FAILURE); };
   pnum->valcount = nbval;
   if (nbval>0) memset (pnum->value, 0, nbval*sizeof(int));
   struct bTreeSon* pson = 
      malloc(sizeof(bTreeSon)+nbsons*sizeof(struct bTreeNode*));
   if (!pson) { perror("malloc bTreeSon"); exit(EXIT_FAILURE); };
   pson->soncount = nbsons;
   for (unsigned ix=0; ix<nbsons; ix++) pson->ptrs[i] = NULL;
   struct bTreNode *pnode = malloc(sizeof(struct bTreeNode));
   if (!pnode) {perror("malloc bTreeNode"); exit(EXIT_FAILURE));
   pnode->numbers = pnum;
   pnode->sons = pson;
   return pnode;
 }

Alternatively you could decide that your nodes have a pointer to the numbers, and a flexible array member for sons (or vice versa)

 // alternatively
 struct bTreeNode {
   unsigned nbsons;
   struct bTreeNumber* numbers;
   struct bTreeNode* sons[]; // actual dimension is nbsons
 };

or even more "old-school" you could have the node know the number of sons and number of values, and keep pointers to (heap-allocated) arrays of them:

 // without flexible members
 struct bTreeNode {
    unsigned nbsons;
    unsigned nbvalues;
    int* pvalues; // point to an array of dimension nbvalues 
    struct bTreeNode** psons; // point to an array of dimension nbsons
 };
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.