Malloc for an array of structs

Started by
5 comments, last by LessBread 18 years, 12 months ago
Well yeah, I need a dynamic array of structs, and so far everything I have seen on the internet is for 2d dynamic arrays. Well the dynamic sized array, is actuallly a member of a struct
Quote: typedef struct GLF_Entry { UI8 charCode; UI32 xPos; UI32 yPos; UI32 iWidth; UI32 iHeight; } GLF_Entry; typedef struct GLF_Font { GLF_Header GLFHeader; UI32 texID; GLF_Entry **GLFEntry; } GLF_Font;
Well the code to allocate the room for the pointers from what I could get off the internet is.
Quote: temp->GLFEntry = (GLF_Entry**) malloc(temp->GLFHeader.charCount * sizeof(GLF_Entry *));
The problem gets me is what now?... How do I actually allocate the space for the structs?
Advertisement
Are you using c or c++? Let's assume c++ for the moment, in which case you'd use 'new' instead of malloc().

So let's say you want to create a dynamic 2d array of class 'Item'. To create a 1d array you'd just do:

Item* items = new Item[numItems];

What you want is an array of arrays of Items, which means you need a pointer to a pointer, like this:

Item** items = new Item*[sizeX];
for (int i = 0; i < sizeX; ++i) items = new Item[sizeY];

Then when you're done:

for (int i = 0; i < sizeX; ++i) delete [] items;
delete [] items;

If you're really just using c, I guess you'll have to use malloc() and cast appropriately. And if you're using c++, another option would be to use std::vector<> and save yourself a lot of hassle.
I dont want to create a 2d array, I want a simple 1d array that I can malloc, then access using GLFEntry[index].

        temp->GLFEntry = calloc(1,temp->GLFHeader.charCount * sizeof(GLF_Entry*));        for (iCounter=0; iCounter < (temp->GLFHeader.charCount+1); iCounter++)        {            temp->GLFEntry[iCounter] = (GLF_Entry*) calloc(1,sizeof(GLF_Entry));            if (!temp->GLFEntry[iCounter])            {                printf("Font open failed could not allocate memory for entries\n");                free(temp);                return NULL;            }        }


Oh and I'm using straight C.
Oh. Well, I'm guessing you would then want GLF_Entry* instead of GLF_Entry**. But, I've never used malloc(), so honestly I'm not exactly sure how you do it in c. I think malloc() allocates the memory and returns a void* which you then have to cast, but I'm not sure.
I wrote a reply to this but my computer overheated and crashed. I'm pretty sure 160°F is way too hot. So I cleaned the heatsink and left to find some thermal paste and forgot all about you.



#include <assert.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>typedef struct GLF_Entry{ int foobie;} GLF_Entry;typedef struct GLF_Font{ GLF_Entry *begin, *end, *alloc_end;} GLF_Font;GLF_Font * GLFcreate(void) {  GLF_Font *font = malloc(sizeof(GLF_Font));  if(!font) return 0;    if(!(font->end = font->begin = malloc(4*sizeof(GLF_Entry))))   {    free(font);    return 0;   }    font->alloc_end = font->begin+4;    return font; }void GLFdestroy(GLF_Font *ptr) {  assert(ptr);    free(ptr->begin);  free(ptr); }int GLFgetSize(GLF_Font *ptr) {  assert(ptr);  return ptr->end - ptr->begin; }GLF_Entry * GLFget(GLF_Font *ptr, int index) {  assert(ptr);  assert(index >= 0);  assert(index < GLFgetSize(ptr));    return ptr->begin+index; }GLF_Entry * GLFgetNew(GLF_Font *ptr) {  assert(ptr);    if(ptr->end == ptr->alloc_end)   {    GLF_Entry *p = realloc(ptr->begin, (ptr->alloc_end-ptr->begin)*2*sizeof(GLF_Entry));        if(!p) return 0;        ptr->end = ptr->end - ptr->begin + p;    ptr->alloc_end = (ptr->alloc_end - ptr->begin) * 2 + p;    ptr->begin = p;   }    GLF_Entry *n = ptr->end;  ++(ptr->end);  return n; }// Removes an element by copying all the elements ahead of it down one index.// Slow, but keeps the elements in order.void GLFremoveStable(GLF_Font *ptr, int index) {  assert(ptr);  assert(index >= 0);  assert(index < GLFgetSize(ptr));    memmove(ptr->begin+index, ptr->begin+(index+1), (--(ptr->end)-(ptr->begin+index))*sizeof(GLF_Entry)); }// Removes an element quickly, buy moving the last element into the location of the deleted element.// Fast, but changes element ordering.void GLFremoveFast(GLF_Font *ptr, int index) {  assert(ptr);  assert(index >= 0);  assert(index < GLFgetSize(ptr));    *(ptr->begin+index) = *(--(ptr->end)); }int main() {  srand(time(0));    GLF_Font *font = GLFcreate();    int c;    printf("Creating some elements. . .\n");    for(c = 0; c < 30; ++c)   GLFgetNew(font)->foobie = c;    printf("Contains %d elements.\n", GLFgetSize(font));    for(c = 0; c < GLFgetSize(font); ++c)   printf("Element %d contains: %d\n", c, GLFget(font, c)->foobie);    printf("Deleting some elements with GLFremoveStable. . .\n");    for(c = 0; c < 10; ++c)   GLFremoveStable(font, rand()%GLFgetSize(font));    printf("Contains %d elements.\n", GLFgetSize(font));    for(c = 0; c < GLFgetSize(font); ++c)   printf("Element %d contains: %d\n", c, GLFget(font, c)->foobie);    printf("Deleting some elements with GLFremoveFast. . .\n");    for(c = 0; c < 10; ++c)   GLFremoveFast(font, rand()%GLFgetSize(font));    printf("Contains %d elements.\n", GLFgetSize(font));    for(c = 0; c < GLFgetSize(font); ++c)   printf("Element %d contains: %d\n", c, GLFget(font, c)->foobie);    GLFdestroy(font);  return 0; }
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other player's eyes with his King.
ummm a simpler solution perhaps? All I want is to be able to dynamically allocate an array of GLFEntry, and access them via GLFEntry[index].
int numberofentries = 16;
GLFEntry *glfentries = malloc( numberofentries * sizeof(*glfentries));

int i = 8;
GLFEntry glfentry = glfentries;

note that glfentries returns a GLFEntry, not a pointer to GLFEntry. That means
that dot notation must be used to access member values.

glfentries.charCode or glfentry.charCode

"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man

This topic is closed to new replies.

Advertisement