Thread: Allocate memory for array that contains struct. Help please.

  1. #1
    Registered User
    Join Date
    Apr 2012
    Posts
    12

    Allocate memory for array that contains struct. Help please.

    Well, I Have 1 struct called Student and 2 called Students. Struct Students has an Array of structs Student. When i pass the second struct after giving the id, name and surname, the program crushes. What is wrong with the code?
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct Student{
        int id;            
        char name[20];    
        char surname[20]; 
    } Student;
    
    typedef struct Students{    
    Student *arr; 
        int size;            
        int sorted; //1 if by surname, name, 2 if by ID
    } Students;
    
    int main(int argc, char *argv[]){
    
    
         Students st;
         Student st1,st2;
    
         st.size=0;     
         st.arr = (Student *) malloc (sizeof(Student));
         printf("Add Student's Information:\n");
         printf("ID: ");
         scanf("%d", &(st1.id));
         printf("Name: ");
         scanf("%s", &(st1.name));
         printf("Surname: ");
         scanf("%s", &(st1.surname));
         st.arr[st.size]=st1;
         (st.size) = (st.size) + 1;
         
         st.arr = (Student *) realloc (st.arr, sizeof(Student));
         printf("Add Student's Information:\n");
         printf("ID: ");
         scanf("%d", &(st2.id));
         printf("Name: ");
         scanf("%s", &(st2.name));
         printf("Surname: ");
         scanf("%s", &(st2.surname));
         st.arr[st.size]=st2;
         printf("%d",st.size);
         (st.size) = (st.size) + 1;
         
         system ("PAUSE");
    }
    Something may be wrong with memory allocation but don't know how to achieve the allocation for the st.arr[1]

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    st.arr = (Student *) malloc (sizeof(Student));
    st.arr = (Student *) realloc (st.arr, sizeof(Student));

    These two lines do exactly the same thing.

    What you really want is something like

    st.arr = malloc (sizeof(Student) * howManyStudents );

    for your initial guess as to how many students you have

    st.arr = realloc (st.arr, sizeof(Student) * howManyStudents );
    then this when you want to expand/contract the array to match your new number of students.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    You have a couple problems with your malloc and realloc calls:

    1. Don't cast the return value of malloc/realloc/calloc. Read this: FAQ > Casting malloc - Cprogramming.com.
    2. You don't check the return value of malloc or realloc to see if they fail.
    3. You don't use a temp pointer, so if realloc fails, you lose the pointer to the original memory, so you can not access it (data loss) or free it (memory leak).
    4. You are still only allocating one Student's worth of memory. You need to multiply by how many Students you need


    Try something like this:
    Code:
    // first time
    st.arr = malloc(sizeof(*(st.arr)));
    if (st.arr == NULL)
        // malloc failed, print error and exit
    
    // second time
    temp = realloc(st.arr, sizeof(*(st.arr)) * (st.size + 1));  // allocate one more element on the end of st.arr
    if (temp == NULL)
        // realloc failed, print error and exit
    st.arr = temp;  // assign the new, longer array to st.arr
    Also notice that I use the variable itself in the sizeof expression instead of the type name. That means if I ever need to change the type of the array, I can do so without worrying about fixing all my malloc calls. Just put the variable you're assigning to inside the sizeof statement, with a * in front.

  4. #4
    Registered User
    Join Date
    Apr 2012
    Posts
    12
    I tried to compile it without the casting at malloc but i got this error: invalid conversion from `void*' to `Student*'
    My problem seemed to be the allocation of realloc. The * (st.size + 1).
    So the realloc and malloc of my code did the same thing. I wasn't allocating memory for the new struct. When i use realloc for one struct, the memory that allocs is the same as the one before with malloc?

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by Grigoris Savvas View Post
    I tried to compile it without the casting at malloc but i got this error: invalid conversion from `void*' to `Student*'
    Sounds like you're compiling your code as C++, not C. What compiler are you using?
    My problem seemed to be the allocation of realloc. The * (st.size + 1).
    So the realloc and malloc of my code did the same thing. I wasn't allocating memory for the new struct. When i use realloc for one struct, the memory that allocs is the same as the one before with malloc?
    [/quote]
    I'm a little confused on your question. It really doesn't matter if it's the same or a different piece of memory. If it's a different piece of memory, realloc will just copy in the necessary data from the old block of memory. If the sizes are exactly the same, I imagine most implementations just return the same piece of memory. I would also guess that most implementations of realloc try to "extend" the memory you had before (or trim it if size is smaller), so that there is no need to copy the data.

  6. #6
    Registered User
    Join Date
    Apr 2012
    Posts
    12
    Yes that's true. My compiler is a C++ one. I thought realloc copies the previous block of memory to a new one and allocates extra memory equals to the size you give. In my situation i used realloc for ONE struct Student. But i have that block of space with malloc and the only thing that realloc does is to copy the previous data to a new block but with no extra space. I got that clear?

  7. #7
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Yes, you are clear on your problem. realloc does not only "allocate extra" according to the size you give, adding it on to the end of ptr. It can also be used to shrink the size of a block of allocated memory. Calling realloc(ptr, size) has 4 basic "behaviors":

    • If ptr is NULL, it acts like malloc(size)
    • If ptr is valid* and size is the same as the size of the original block of memory, nothing happens.
    • If ptr is valid* and size is less than the size of the original block of memory, the excess is "chopped off". The contents of the memory, up to the new, smaller size limit are unchanged.
    • If ptr is valid* and size is greater than the size of the original block of memory, the end of the allocated block is "extended". The new memory is uninitialized (i.e. contains garbage).


    For cases 2-4, realloc may allocate a whole new chunk of memory and copy the old contents in, then free the old piece of memory, but it is not required to do so. Most implementations of realloc would probably try to reuse the same block and just move the end of it accordingly, for efficiency reasons.

    * A valid pointer is anything that was previously returned by a call to malloc, calloc or realloc.

  8. #8
    Registered User
    Join Date
    Apr 2012
    Posts
    12
    Thanks a lot. I fully understand the realloc function and the mistakes of my codes. I will do some more research on casting to undrestand it more. Thanks again!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 04-02-2012, 07:38 PM
  2. declare pointer and allocate memory for an array typedef
    By Amar Akshat in forum C Programming
    Replies: 2
    Last Post: 12-28-2011, 03:31 AM
  3. Dynamically allocate memory to create 2D array
    By nonlinearly in forum C Programming
    Replies: 15
    Last Post: 11-10-2011, 02:22 AM
  4. Allocate memory for an Array
    By Coding in forum C++ Programming
    Replies: 3
    Last Post: 01-05-2008, 06:18 PM
  5. How to allocate memory in multidimensional array?
    By Unregistered in forum C Programming
    Replies: 6
    Last Post: 10-15-2001, 10:07 AM