0

I need some ideas on my array of struct implementation. This is what I have in my structs. I plan on making SHAPES an array because I will have multiple SHAPES. Each shape will have multiple x and y coordinates. Because of this I'm not sure if should make a linked list or not. The purpose of the start and finish is I will eventually be running a search algorithm after I get my shapes right.

struct START
{
    int x; 
    int y;
};
struct END
{
    int x; 
    int y;
};
struct SHAPES
{
    int x [100]; 
    int y [100];
    int *link;
};
struct DISTANCE
{
    int distance_traveled; 
    int distance_to_finish;
};

I was reading this and was wondering if I needed to malloc or calloc my structs as I create them. If so why and if not why? Malloc and calloc are always confusing to me.

How do you make an array of structs in C?

int main(int argc, char *argv[])
{

    //Is it better to make these pointers? 
    struct START start;
    struct END end;
    struct SHAPES shapes[100];

    while(fgets(line, 80, fp) != NULL)
    {
        //I have a very annoying issue here, I don't know the size of the lines. 
        //If there are more values I want to increment the x[] and y[] array but NOT the 
        //shapes array. I can only think of one way to deal with this by putting a bunch of 
        //variables in the sscanf. I discovered putting sscanf on the next line didn't do what 
        //I was hoping for. 
        sscanf(line, "%d%*c %d%*c ", &shapes[i].x[i] , &shapes[i].y[i] );
        printf(" line is: %s \n", line);
        sscanf(line, "%d%*c %d%*c ", &x1_main , &y1_main );
        printf(" line is: %s \n", line);
        printf(" shapes[i].x[i] is: %d \n", shapes[i].x[i]);
        printf(" shapes[i].y[i] is: %d \n", shapes[i].y[i]);
        printf(" x1_main is: %d \n", x1_main);
        printf(" y1_main is: %d \n", y1_main);
        i++;
        memset(line, 0, 80);
    }

}

This is what my file looks like. Adding the %*c seemed to handle the commas and semicolons appropriately.

10, 4
22, 37
22, 8; 2, 0; 3, 6; 7, 8; 5, 10; 25, 2
1, 2

I got that idea from here.

https://www.daniweb.com/software-development/c/threads/334515/reading-comma-separated-values-with-fscanf

7
  • It is not clear why you have separate types for START and END (or why you like shouting; normally, reserve all upper-case names for macros, not for types — the standard FILE * and POSIX DIR * notwithstanding). Surely, you could call this 'Position', and then your Shape should contain an array of Position values. There's no self-evident reason to create a linked list of shapes. If you use C99 or C11, you might consider using a flexible array member, but that might also be pushing you too hard as yet. Commented Oct 13, 2014 at 7:29
  • To deal with unknown numbers of entries in a line, consider How to use sscanf() in loops? Commented Oct 13, 2014 at 7:33
  • I have a strong suspicion that your use of 100 shapes in an array when each shape can hold one hundred points is misguided. You should fill up the first 100 points in one shape before moving to another entry in the array, I think. Commented Oct 13, 2014 at 7:38
  • As to malloc() etc: you use those when either the array will be too big to allocate on the stack or its size won't be known until run-time and any pre-allocation may be too small (or will need to use too much space to be sensible). Use arrays when you can; use lists when you must. Arrays give you easy access to any element, but it is hard to remove or add an element in the middle of an array. Lists are flexible (it is easy to add and possible to remove from the middle of a list), but finding a particular element in the list is typically slow compared to using an array. Commented Oct 13, 2014 at 7:40
  • @JonathanLeffler The purpose for the start and end is because I will be running a search algorithm after I properly build my shapes. I need the Start and End to properly run the algorithm. Commented Oct 13, 2014 at 7:55

2 Answers 2

1

First of all, you might want to consider something like this:

struct point {
      int x;
      int y;
};

so you can use a struct point data structure (array) instead of two separate data structures for x and y. Using it like this should also speed up access to the points, since their coordinates are next to each other in memory. Otherwise you will have x somewhere in the x array and y somewhere in the y array.

The choice of the data structure to store the points depends on your usage. If you need to address points directly, a linked list may be a bad choice. If you always access all points in a linear order, it is fine. However, consider that a singly linked list will add 8 bytes per point for the next pointer. A doubly linked list will use another 8 bytes for prev (assuming 64-bit arch that is; sizeof(pointer) in general). I assume, that you create x[100] and y[100] to make sure you have enough space. You might be better off using a dynamic array (the ADT) e.g. glib's GArray after all. It will grow as big as you need it without you doing anything.

For malloc vs calloc: it doesn't really matter. A call to calloc is basically a malloc followed by a

memset(ptr, 0, sizeof(mallocd area);

i.e. the memory is zeroed; cf manpage calloc. If you initialize the memory directly you may not need to do this.

Sign up to request clarification or add additional context in comments.

Comments

0

A struct with no pointer members
If your struct has no pointer members, such as:

typedef struct {
    int a;
    int b;

} DEMO;  

Then you can simply declare an array instance of a typedef struct like this:

DEMO demo[10];// instance of array of 10 DEMO

Example, struct with Pointer members
If you have a pointer in the list of members:

#define SIZE_STR 20

typedef struct {
    int a;
    int b;
    char *str;//pointer, will require memory allocation
} DEMO;

DEMO demo[10];// instance of array of 10 DEMO

int main(void)
{
    int i;

    for(i=0;i<10;i++)//create memory for each instance of char * in array of DEMO
    {   
        demo[i].str = malloc(SIZE_STR); 
    }
    return 0;
}  

Don't forget to free() all instances of malloc'ed memory.

Dynamically allocate array of struct
If you need to dynamically allocate memory for a struct:

typedef struct {
    int a;
    int b;
} DEMO;  
DEMO demo, *pDemo;// create a pointer to DEMO

In a function, main() for example:

int main(void)
{
    pDemo = &demo;  
    pDemo = malloc(sizeof(DEMO)*10);//provides an array of 10 DEMO
    return 0;
}  

Again, don't forget to free() all instances of malloc'ed memory.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.