Jump to content
  • Advertisement
Sign in to follow this  
Arenth

Malloc for an array of structs

This topic is 4780 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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;
}

Share this post


Link to post
Share on other sites
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].

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!