Thread: Simple allocating question.

  1. #1
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256

    Simple allocating question.

    In the FAQ on pointers, it is mentioned that you must "free" memory that you allocate. How would this be done?

  2. #2
    Registered User Bajanine's Avatar
    Join Date
    Dec 2001
    Location
    The most peaks over 10,000 feet!
    Posts
    396
    free

    [edit]
    removed c++ link as this is the c forum. Stupid me!
    [/edit]
    Last edited by Bajanine; 03-30-2005 at 09:33 PM.
    Favorite Quote:

    >For that reason someone invented C++.
    BLASPHEMY! Begone from my C board, you foul lover of objects, before the gods of C cast you into the void as punishment for your weakness! There is no penance for saying such things in my presence. You are henceforth excommunicated. Never return to this house, filthy heretic!



  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    184
    Code:
    int main()
    {
         int *p;
    
         p=malloc(sizeof int);
         . . . . . 
         . . . . .
    
    
         free(p);  // free the memory which was allocated before
    
        return 0;
    }
    s.s.harish

  4. #4
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    Thanks. But, I think I may still need some lessons on using malloc and realloc.

    Here's a small code I've been working with to try an teach myself about how to use the functions.
    Code:
    #include <stdio.h>
    #include <stdlib.h> //is this necessary for *alloc functions?
    
    int loop = 0;
    char entry;    //both this and above are purely for keeping the windown from closing
    int answer;
    int *ptr;
    int *ptr2;
    
    main()
     {
      while(loop == 0)
       {
        ptr = malloc(sizeof(int));
        answer = sizeof(ptr);
        printf("%i\n", answer);
        answer = sizeof(*ptr);
        printf("%i\n", answer);
        ptr2 = malloc(8);
        answer = sizeof(ptr2);
        printf("%i\n", answer);
        answer = sizeof(*ptr2);
        printf("%i\n", answer);
        scanf("%c", entry);
       }
     }
    The problem now is that my output is
    Code:
    4
    4
    4
    4
    Is there actually a problem with my code or is my logic just wrong in thinking that one of the outputs should be eight?

  5. #5
    Registered User Bajanine's Avatar
    Join Date
    Dec 2001
    Location
    The most peaks over 10,000 feet!
    Posts
    396
    Your just printing out the size of a pointer, not the size of what is pointed too! So at least to my novice eyes 4 looks correct.

    [edit]
    Don't forget it is:
    Code:
      int main() // not main()
    Also don't forget to return an int.
    [/edit]
    Last edited by Bajanine; 03-30-2005 at 09:30 PM.
    Favorite Quote:

    >For that reason someone invented C++.
    BLASPHEMY! Begone from my C board, you foul lover of objects, before the gods of C cast you into the void as punishment for your weakness! There is no penance for saying such things in my presence. You are henceforth excommunicated. Never return to this house, filthy heretic!



  6. #6
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    That's what I was thinking, but if you notice, on the first sizeof operation of each one, I only have the name of the pointer, but on the second, I have the dereferance operator (*), which means that it should be taking the sizeof ptr dereferanced, which should be the malloced memory address. Is this not true?

  7. #7
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by Jaken Veina
    That's what I was thinking, but if you notice, on the first sizeof operation of each one, I only have the name of the pointer, but on the second, I have the dereferance operator (*), which means that it should be taking the sizeof ptr dereferanced, which should be the malloced memory address. Is this not true?
    This is not true. If ptr is a pointer to an int, then what it is pointing to is an int. The size of an int is sizeof(int). So the size of the thing being pointed to by an int pointer (sizeof(*ptr)) is sizeof(int).
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  8. #8
    Registered User Bajanine's Avatar
    Join Date
    Dec 2001
    Location
    The most peaks over 10,000 feet!
    Posts
    396
    Wow, it's time for an 8 hour nap! I didn't even see it.
    Favorite Quote:

    >For that reason someone invented C++.
    BLASPHEMY! Begone from my C board, you foul lover of objects, before the gods of C cast you into the void as punishment for your weakness! There is no penance for saying such things in my presence. You are henceforth excommunicated. Never return to this house, filthy heretic!



  9. #9
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    But what about ptr2, where instead of being malloced to the sizeof(int) or 4, it's malloced to 8. Yet, sizeof(*ptr2) is still being read as 4. Shouldn't sizeof(*ptr2) be 8, since I malloced it to 8?

  10. #10
    Registered User
    Join Date
    Mar 2005
    Location
    New Zealand
    Posts
    20
    Even though you've allocated 8 bytes of memory to it, it doesn't change sizeof(int) which is what you are effectively doing. The size of the allocated space is stored internally by the program (you can get access to it, but it is really really really bad practice - from memory its stored in the 4 bytes previous to the array memory location). A better way of doing it is to have a second variable which holds the size of the array. Also you should use sizeof() when allocating memory just to make sure the right amount has been allocated.

    What I would recommend doing is:
    Code:
       int *ptr;
       int ptrLen = 8;
       ptr = malloc(sizeof(int) * ptrLen);     Allocate enough memory for 8 ints. (32 bytes normally)
       *ptr = 4;     //Access first element in array
       ptr[1] = 1;   //access second element in array
       *(ptr+5)= 2;  //access 6th element in array.
       *++ptr=2;     //This is bad because it changes where ptr is pointing and so free(ptr) won't work.
    Last edited by FlyingDutchMan; 03-30-2005 at 10:30 PM.

  11. #11
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    So, basically, sizeof(*ptr) doesn't output the allocated size. That's kinda what I thought from the beginning. Pooie. One of the main reasons I wanted to learn about allocating is so I could get rid of those extra variables that store the number of elements in a flexible array. Okay, then. Back to the easy questions!


    #1:
    Code:
    struct letter
    {
     char a;
     char b;
     char c;
     char d;
     char e;
    }
    
    struct letter* exmp;
    
    main()
     {
      exmp = malloc(sizeof(*exmp) * 2);
     }
    Using this code, would I simply access the values of exmp like so?
    Code:
    exmp[0].a = 0;
    exmp[0].b = 1;
    exmp[0].c = 2;
    exmp[0].d = 3;
    exmp[0].e = 4;
    exmp[1].a = 5;
    exmp[1].b = 6;
    exmp[1].c = 7;
    exmp[1].d = 8;
    exmp[1].e = 9;
    #2:
    Is the realloc in this correct?
    Code:
    main()
     {
      int* ptr = malloc(sizeof(*ptr));
      ptr = realloc(sizeof(*ptr) * 5);
     }

  12. #12
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by Jaken Veina
    So, basically, sizeof(*ptr) doesn't output the allocated size. That's kinda what I thought from the beginning. Pooie. One of the main reasons I wanted to learn about allocating is so I could get rid of those extra variables that store the number of elements in a flexible array. Okay, then. Back to the easy questions!


    #1:
    Code:
    struct letter
    {
     char a;
     char b;
     char c;
     char d;
     char e;
    }
    
    struct letter* exmp;
    
    main()
     {
      exmp = malloc(sizeof(*exmp) * 2);
     }
    Using this code, would I simply access the values of exmp like so?
    Code:
    exmp[0].a = 0;
    exmp[0].b = 1;
    exmp[0].c = 2;
    exmp[0].d = 3;
    exmp[0].e = 4;
    exmp[1].a = 5;
    exmp[1].b = 6;
    exmp[1].c = 7;
    exmp[1].d = 8;
    exmp[1].e = 9;
    Yeah, that would work. You can always compile it and find out what it does. For example, had you compiled this, you'd have discovered that you left out a semi-colon on your origional structure definition.

    Quote Originally Posted by Jaken Veina
    #2:
    Is the realloc in this correct?
    Code:
    main()
     {
      int* ptr = malloc(sizeof(*ptr));
      ptr = realloc(sizeof(*ptr) * 5);
     }
    No. It's not. There are actually two problems:

    1) Your call to realloc is wrong, because you forgot to pass it a pointer to what is actually going to be reallocated. Thus:
    Code:
    realloc( ptr, sizeof( *ptr ) * 5 );
    2) Your handling of the return value is dangerous in that, if realloc fails, it returns NULL, thus destroying any chance you have at freeing whatever you had allocated previously.

    This gives us a final version of:
    Code:
    int *ptr, *temp;
    
    ptr = malloc( sizeof( *ptr ) );
    if( ptr )
    {
        temp = realloc( ptr, sizeof( *ptr ) * 5 );
        if( temp )
        {
            ptr = temp;
        }
    }
    Quzah.
    Hope is the first step on the road to disappointment.

  13. #13
    C maniac
    Join Date
    Aug 2004
    Location
    Cyberwarping to Middle Earth
    Posts
    154

    Arrow operator

    To access members of a struct when that struct is a pointer, you need to use the arrow operator ('->') instead of the dot operator ('.'):

    Code:
    struct s {
    	char data;
    } *p;
    p = (struct s *) malloc (sizeof(struct s));
    p->data = 'A';
    free(p);
    What you had before was

    Code:
    struct s {
    	char data;
    } *p;
    p = (struct s *) malloc (sizeof(struct s));
    p.data = 'A';  // <<< that won't work
    free(p);
    Here's how you use the dot operator:

    Code:
    struct {
    	char data;
    } s;
    p.data = 'A';

  14. #14
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by kawk
    To access members of a struct when that struct is a pointer, you need to use the arrow operator ('->') instead of the dot operator ('.'):

    Code:
    struct s {
    	char data;
    } *p;
    p = (struct s *) malloc (sizeof(struct s));
    p->data = 'A';
    free(p);
    What you had before was

    Code:
    struct s {
    	char data;
    } *p;
    p = (struct s *) malloc (sizeof(struct s));
    p.data = 'A';  // <<< that won't work
    free(p);
    No they didn't. Now you're just making ........ up. They had no such thing. Even if they did, which they didn't, their use of it would still be valid. Watch:
    Code:
    #include <stdio.h>
    
    int main( void )
    {
        struct foo
        {
            int bar;
        } instance, *pointer;
    
        pointer = &instance;
    
        pointer[0].bar = 10;
    
        printf("instance.bar is %d\n", instance.bar );
        printf("pointer->bar is %d\n", pointer->bar );
        printf("pointer[0].bar is %d\n", pointer[0].bar );
    
        return 0;
    }
    
    
    /*
    $ gcc -o dotop dotop.c -Wall -pedantic -ansi
    $ dotop
    
    instance.bar is 10
    pointer->bar is 10
    pointer[0].bar is 10
    
    */
    As I already stated, it's perfectly legal to do what they've described.

    Quzah.
    Hope is the first step on the road to disappointment.

  15. #15
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    *smacks self*

    Bah. How could I have forgotten to argue the address in realloc.

    And you are very correct with the temp pointer, quzah. Thanks for pointing that out.

    And if I remember correctly, the memory allocated orriginally is freed by realloc and more memory is allocated (if it is successful). So, to free this new memory, I would just use free(ptr), correct?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Simple question regarding variables
    By Flakster in forum C++ Programming
    Replies: 10
    Last Post: 05-18-2005, 08:10 PM
  2. Simple class question
    By 99atlantic in forum C++ Programming
    Replies: 6
    Last Post: 04-20-2005, 11:41 PM
  3. Simple question about pausing program
    By Noid in forum C Programming
    Replies: 14
    Last Post: 04-02-2005, 09:46 AM
  4. simple question.
    By InvariantLoop in forum Windows Programming
    Replies: 4
    Last Post: 01-31-2005, 12:15 PM
  5. simple fgets question
    By theweirdo in forum C Programming
    Replies: 7
    Last Post: 01-27-2002, 06:58 PM