free memory on a array

This is a discussion on free memory on a array within the C Programming forums, part of the General Programming Boards category; hi, first of all, english isn't my native languaje so plz excuse me if i write something wrong i made ...

  1. #1
    Registered User
    Join Date
    Dec 2008
    Posts
    4

    free memory on a array

    hi, first of all, english isn't my native languaje so plz excuse me if i write something wrong


    i made a program that allow me to work with a "dynamic array"

    Code:
    int main(){
    	int x=10, y=0;
    	char *word;
    	word=(char *) malloc(x*sizeof(char));
    	while((word[y]=getchar())!='\n'){
    		y++;
    		if(x==y){
    			x*=2;
    			word=(char *) realloc(word,(x*sizeof(char)));
    		}
    	}
    	word[y]='\0';
    	
    	printf("%s\n",word);
    	
    }
    this code works fine, my problem comes when i want to free the memory allocated that isn't being used...

    [ I ][ I ][ I ][ I ][ I ][ I ][ I ][ \0 ][O][O][O][O][O]

    i thought in some possible solutions but none of them seems perfect.

    1: Use free(), giving the array pointer as parameter and trying to move it to where the array ends..

    [ I ][ I ][ I ][ I ][ I ][ I ][ I ][ \0 ][O][O][O][O][O] <-- i tried to "move" the pointer to the position next to \0 and use free() to release the memory.. but this didn't work, free doesn't allow the use of a pointer plus something (example: free(word+1) )

    i don't know why this doesn't work and i would really appreciate if someone can explaint it to me...


    2.- I read that realloc allows to increase or decrease space, so i thought that using it again over the pointer would reallocate the memory correctly.. but the problem is that i don't really know what happens with the memory that isn't reallocated

    word=(char *) realloc(word,(strlen(word))*sizeof(char)); <-- that's the code


    3.- the third option is to create another array and use strlen to allocate the exact space and then free the other array

    char *dog = (char *) malloc( (sizeof(char)) * strlen(word));
    strcpy(dog,word);
    free(word);

    seems good to me too, but what if i don't have enough memory to create another array? (assuming that the user writes one billion characters :zippy)


    the second and third options works (i think 2 is the best)
    but i would be grateful if anyone can give me an opinion

  2. #2
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    Use realloc() to resize.
    http://linux.die.net/man/3/realloc
    Last edited by Bayint Naung; 08-21-2010 at 02:05 AM.

  3. #3
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,047
    Code:
    word=(char *) realloc(word,(strlen(word))*sizeof(char)); <-- that's the code
    Be careful with this. You almost certainly want strlen(word) + 1, in order to leave space for the NULL character \0.

    The reason your option (1) (freeing some memory from the middle of the array) doesn't work is due to the way memory is allocated. The operating system (or the standard C library, as libc does on Linux) maintains a list of blocks of memory that you have allocated. When new allocation requests are made, the system will try to fit it into existing pages and if this does not work, allocate more pages.

    But they key point is that only pointers to the beginning of allocated blocks can be manipulated. It could have been designed so that you could free memory in the middle of a block as you have described, but it would be expensive (perhaps) for the memory allocation code to find out which block of allocated memory a random pointer belongs to.

    Anyway, I'm not sure of the exact reason it was designed this way, but it was, and dynamically allocated memory can only be manipulated by pointers to the first element. (If you try otherwise you could get nasty messages like "*** glibc heap corruption detected", which is the standard library noticing that you're using pointers that weren't dynamically allocated.)
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  4. #4
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,528
    Quote Originally Posted by Telomin View Post
    3.- the third option is to create another array and use strlen to allocate the exact space and then free the other array

    char *dog = (char *) malloc( (sizeof(char)) * strlen(word));
    strcpy(dog,word);
    free(word);
    Something you will want to keep in mind is that your call to malloc() does not allocate enough space for your string. strlen() calculates the length of the string word, but does not include the terminationg '\0'. You will need to do that yourself:

    Code:
    dog = malloc(strlen(word) * sizeof *word + 1);
    Also, see here for why I did not cast the return value of malloc().

    Edit:

    Doh! Beat by dwks' speedy typing!
    Last edited by kermit; 08-21-2010 at 07:04 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to read a txt file into an array
    By Hitsugaya_KK in forum C Programming
    Replies: 49
    Last Post: 08-22-2009, 02:22 PM
  2. To find the memory leaks without using any tools
    By asadullah in forum C Programming
    Replies: 2
    Last Post: 05-12-2008, 07:54 AM
  3. Class Template Trouble
    By pliang in forum C++ Programming
    Replies: 4
    Last Post: 04-21-2005, 04:15 AM
  4. How to free memory in this program
    By Coconut in forum C Programming
    Replies: 1
    Last Post: 10-26-2002, 10:57 PM
  5. Help with an Array
    By omalleys in forum C Programming
    Replies: 1
    Last Post: 07-01-2002, 08:31 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21