0

I am attempting to develop a dynamically-allocated circular-buffer in C using two structs. One holds detailed information and another is essentially used as a pointer from main to the circular-buffer structure (as there will be multiple arrays allocated at runtime).

Since it is a circular-buffer, I have a pointer "next" which points to the next item in the array (so last array index points to the first, etc.)

These are the two struct objects I have:

typedef struct {
    int a;
    int b;
    struct1 *next;   // pointer to next struct1 object in array
} struct1;

typedef struct {
    struct1 *curr;     
    struct1 *start = NULL;
    struct1 *end = NULL;
} struct2;

I then have my initialize function that is called from main to initiate a new circular-buffer.

This is the part where I am not entirely sure what to do.

#define minSize 10
struct2 * initialize()
{   
    struct2 **newBuf = malloc(sizeof(*newBuf));
    newBuf->malloc(sizeof(*newBuf->quotes) * newBuf->minSize);

    // set the start pointer
    newBuf.curr[0] = newBuf->start;
    newBuf.curr[0]->next = NULL;

    for (int i = 1; i < minSize; i++)
    {
        struct1 *new = NULL;     
        newBuf.curr[i] = new;    // make index i = NULL
        // have the previous index point to the "next" current
        if (i > 0)
            newBuf.curr[i-1]->next = newBuf.curr[i];
    }

    // connect last index with first
    newBuf.curr[minSize - 1]->next = newBuf.curr[0];

    // set the end pointer  
    newBuf->end = newBuf->start;

    return newBuf;
}

From searching I found this answer on how to initialize an array of structs within a struct by using malloc for initially allocating the space, but am confused how my code would line up since I have pointers to define start and end of the circular-buffer defined in struct2, as well as the next pointer as part of struct1.

Additionally, I've chosen to define ***newBuf* instead of **newBuf* as I was considering it as a pointer to pointers in a way (thinking about singly-linked lists). Though, please correct me if I am wrong.

I've done dynamically allocated circular-buffers in Java, but not C nor C++, so I am having a hard time figuring out the differences in how to initialize everything. I'm basically stuck at this mess and not sure where to go next.

Any help that can be given would be much appreciated!

Community
  • 1
  • 1
sudo_coffee
  • 888
  • 1
  • 12
  • 26
  • `typedef struct { struct1 curr[]; ` does not compute. Please post real code. Maybe you'll get real answers. – wildplasser Apr 07 '13 at 23:24
  • Yes it does, wildplasser: http://en.wikipedia.org/wiki/Typedef – Rob G Apr 07 '13 at 23:35
  • 1
    No @RobG. The OP *could* have meant a VLA, but that is only valid as the last element in a struct. Anyway: he corrected it. Conclusion: it was *not real code*. – wildplasser Apr 07 '13 at 23:43
  • @wildplasser struct1 curr[] was what I initially had, but changed it in my code after finding the link I posted in my post. Forgot to update it in code pasted here, though. It is _real code_, the only things changed were variable names in struct1 (to _a_ and _b_). – sudo_coffee Apr 07 '13 at 23:59
  • and the `newBuf->malloc` is actually a function pointer ? – wildplasser Apr 08 '13 at 00:03
  • Pure mistype, which is why nothing would compile. Still learning full capabilities of malloc, so that was part of one (of many) attempts to see what would happen. Result: compile errors. Never said my code was working when I posted it. – sudo_coffee Apr 08 '13 at 00:06

1 Answers1

1

The reason you're running into trouble is because you're trying to have the pointer to a pointer, rather than just using an ordinary pointer. You want to access the pointer that is contained at the address pointed to by the first pointer. As it stands you're trying to access a member that is outside of the memory space of the original pointer's address (which is only as large as an address). And then you're running into trouble because you aren't initializing your array 'curr' either. Another thing I did that doesn't really matter but helps you understand pointers is made your array a pointer- which is how arrays work in C. The array is simply the address of the first member of the array, and when you index into the array, it just adds an offset to that address = index * sizeof(yourstruct).

What you want is

typedef struct {
   struct1 *curr;     
   struct1 *start = NULL;
   struct1 *end = NULL;
} struct2;

#define minSize 10
struct2* initialize()
{   
 struct2 *newBuf = (struct2 *) malloc(sizeof(struct2));
 newBuf->curr = (struct1 *) malloc(sizeof(struct1) * minSize);

// set the start pointer
 newBuf.curr[0] = newBuf->start;
 newBuf.curr[0]->next = NULL;

 for (int i = 1; i < minSize; i++)
 {
    struct1 *new = (struct1 *) malloc(sizeof(struct1));
    newBuf.curr[i] = new;
    newBuf.curr[i-1]->next = newBuf.curr[i];
 }
  // connect last index with first
  newBuf.curr[minSize - 1]->next = newBuf.curr[0];
  // set the end pointer  
  newBuf->end = newBuf->start;
  return newBuf;
}
Rob G
  • 3,496
  • 1
  • 20
  • 29
  • I see, so each call within the forloop needs to be allocated in memory as well. That makes a lot of sense. This cleared up many other issues I was having in the same file with memory allocation. Thank you! – sudo_coffee Apr 07 '13 at 23:38
  • 1
    There is no reason to cast the return value you get from malloc(). (and the usual silly excuse that that is to allow C++ compilers to accept the code is anihilated by the presence of `new` as a variable name) Also, the idiom `ptr = malloc( cnt * sizeof *ptr);` in the OP is more robust than your `ptr = malloc (cnt * sizeof (Type));` . – wildplasser Apr 08 '13 at 00:20