Initializing array of structures causing bus error

This is a discussion on Initializing array of structures causing bus error within the C Programming forums, part of the General Programming Boards category; I'm having this annoying bus error. I've defined two structures, and defined two types which point to these structures. Code: ...

  1. #1
    Registered User
    Join Date
    Mar 2006
    Location
    Halifax, N.S.
    Posts
    4

    Unhappy Initializing array of structures causing bus error

    I'm having this annoying bus error.

    I've defined two structures, and defined two types which point to these structures.
    Code:
    struct node {
           /* ... */
    };
    typedef struct node* NodeP; // NodeP points to a node.
    
    struct graph {
            /* ... */
    
            NodeP* nodes; // Will be an array of node pointers.
    };
    typedef struct graph* GraphP; // GraphP points to a graph.
    So, GraphP would point to a graph structure, which will have an array of pointers to node structures when initialized.

    My problem is after I initialize <nodes> for a GraphP, I get a bus error when I try to put a NodeP into it.

    This is how I create a GraphP:
    Code:
    GraphP newGraph(int length) {
            GraphP newGraph = (GraphP)malloc(sizeof(GraphP));
    
            /* Initialize other variables of newGraph. */
    
            newGraph->nodes = (NodeP*)calloc(length, sizeof(NodeP));
    
            NodeP testNode = newNode(); // A test node pointer.
    
            // Set all the elements of newGraph->nodes to equal testNode.
            int i;
            for(i = 0; i < length; i++)
                    newGraph->nodes[i] = testNode; // Bus error here.
    
            return newGraph;
    }
    Can someone tell what's going wrong?

    Thanks.

  2. #2
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,490
    > typedef struct node* NodeP;
    Using typedef to hide pointers is generally a bad idea IMO. For one thing, it hides the true level of indirection in several places. For another thing, it makes it much harder to add certain combinations of qualifiers (const, volatile) to the declaration.

    Regarding information hiding.
    node **nodes;
    It is easier to see that this has two levels of indirection whereas it is a lot less obvious that this is the case with
    NodeP* nodes;

    > GraphP newGraph = (GraphP)malloc(sizeof(GraphP));
    1. casting malloc in C does nothing for you - see the FAQ for reasons. Given some of your other code (embedded declarations), are you sure this isn't a C++ program?
    2. naming the variable to be the same as the function is poor - it's called shadowing, and can lead to some rather weird scope problems (just try making your function recursive for example).

    > newGraph->nodes = (NodeP*)calloc(length, sizeof(NodeP));
    Why did you switch to calloc here?
    It isn't adding anything special, except you get to avoid having to do a multiply yourself.

    > Can someone tell what's going wrong?
    Well in isolation, there is nothing wrong with the code per se, so my guess is some other malloc/free mistake elsewhere in the code is the cause, and this is just where the symptoms of the problem show up to bite you.
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    
    typedef struct node {
      int n1;
    } node;
    
    typedef struct graph {
      node  **nodes;
    } graph;
    
    node *newNode ( void ) {
      node *result;
      result = malloc ( sizeof *result );
      return result;
    }
    
    graph *newGraph(int length) {
      graph *newGraph = malloc(sizeof *newGraph );
      node  *testNode = newNode();
      int i;
    
      newGraph->nodes = malloc(length * sizeof *newGraph->nodes );
      for(i = 0; i < length; i++)
        newGraph->nodes[i] = testNode;
    
      return newGraph;
    }
    
    int main (void)
    {
      graph *new = newGraph( 10 );
      printf( "p=%p\n", (void*)new );
      return 0;
    }

  3. #3
    Registered User
    Join Date
    Mar 2006
    Location
    Halifax, N.S.
    Posts
    4
    Thanks Salem. I made the improvements you suggested about using typdef and malloc.

    I noticed that when you use sizeof you pass an actual pointer instead of a type name. Is there any particular reason for that?

  4. #4
    Registered User
    Join Date
    Mar 2006
    Posts
    2
    Not to derail the thread or anything but what does this line do?

    Code:
    printf( "p=%p\n", (void*)new );

  5. #5
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,069
    Quote Originally Posted by Aaron M
    Thanks Salem. I made the improvements you suggested about using typdef and malloc.

    I noticed that when you use sizeof you pass an actual pointer instead of a type name. Is there any particular reason for that?
    The reason you pass the variable name is because sometimes you may want to edit the program in the future to accommodate a different type. Rather than going through all of your code changing every single malloc() call to suit your new datatype you simply have to change the variable's datatype and that will affect everything. It's like an inline function that outputs a single repetitive line. You make it so it makes future edits easier.
    Sent from my iPadģ

  6. #6
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,490
    Basically what Sly said.

    By doing
    Code:
    p = malloc ( sizeof *p );  // for 1
    p = malloc ( num * sizeof *p );  // for num
    means you don't have to look back at the variable to see how it was declared just to allocate space, and you have less to maintain in the future.

    Although it looks like you're dereferencing a pointer, remember that sizeof is a compile time operator, so the only thing being dereferenced is the type information in the compiler symbol table.

    > Not to derail the thread or anything but what does this line do?
    It prints a pointer - try it.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. how do you resolve this error?
    By -EquinoX- in forum C Programming
    Replies: 32
    Last Post: 11-05-2008, 03:35 PM
  2. Errors including <windows.h>
    By jw232 in forum Windows Programming
    Replies: 4
    Last Post: 07-29-2008, 01:29 PM
  3. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 01:53 AM
  4. Problem with Visual C++ Object-Oriented Programming Book.
    By GameGenie in forum C++ Programming
    Replies: 9
    Last Post: 08-29-2005, 11:21 PM
  5. Linking error
    By DockyD in forum C++ Programming
    Replies: 10
    Last Post: 01-20-2003, 04:27 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21