Thread: Realloc Quick Question.

  1. #1
    Registered User
    Join Date
    Nov 2008
    Posts
    44

    Realloc Quick Question.

    Right i've allocated space in memory for.

    Code:
    temp = calloc( 30, sizeof( char ) ) ;
    This array then gets thrown into a list and another word put into it, then into the list etc. What i'm trying to do, once the word is in the array is to realloc the array down to the right size. I am currently doing

    Code:
    temp = realloc( temp, i*sizeof( char ) ) ;
    I want to use the integer i to resize as it knows the size as i read the characters in one by one. But it doesn't like it. Does it have to be a number value? Also i have read somewhere that realloc doesn't remove anything just removes whatever is not used. So could i just put a value of 1 in there instead??

    Cheers.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Quote Originally Posted by killpoppop
    But it doesn't like it.
    What is the first "it", and how do you know that "it doesn't like it"?

    One potential problem is that you assign the result of realloc() to temp, which means that if realloc() returns NULL you have no way to freeing the memory. Also, note that sizeof(char) is always 1.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Nov 2008
    Posts
    44
    Um like if i replace 'i' with say 20 it does it fine. Even if i change it to 5 it still takes words bigger than 5 ( does that mean its not working or how realloc works? ) whenever i use 'i' it crashes.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Quote Originally Posted by killpoppop
    Even if i change it to 5 it still takes words bigger than 5 ( does that mean its not working or how realloc works? )
    Yes, realloc() would not resize to a smaller size.

    Quote Originally Posted by killpoppop
    whenever i use 'i' it crashes.
    Post the smallest and simplest program that demonstrates the problem. Incidentally, what is the value of i at that point?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    Your call to realloc is fine (aside from not handling the NULL case), in terms of how realloc is used. My best guess from your wording is that you're doing something like this...

    Code:
    temp = calloc(30, sizeof(char));
    
    strncpy(temp, SomeSortOfInput, 30);
    
    //Since the input string is probably less than 30 characters, lets get rid of what we don't need...
    int i;
    for(i = 0; temp[i] != 0; ++i);
    
    // The for loop stopped at the '\0' terminator, so i is the size of the string...
    temp = realloc(temp, i * sizeof(char));
    There's several problems you may be running into if you're doing something like the above. Firstly, if you used strcpy instead of strncpy, you could easily run past the end of temp in multiple places. But the problem I think you're probably having is that after the for loop, i doesn't contain the size of the string. It contains the location of the null terminator. Therefore, when you call realloc, it realloc's only up to the null terminator, but not including it, so when you work with the string later on, you're running way off into nowhere. The call to realloc, in this case, needs to be

    Code:
    temp = realloc(temp, (i + 1) * sizeof(char));
    But depending on what your checking conditions are in the for loop, you may or may not need the +1, or you may need something else entirely.
    Code:
    void function(void)
     {
      function();
     }

  6. #6
    Registered User
    Join Date
    Nov 2008
    Posts
    44
    Code:
    char read( FILE *text )
    {
    	int i = 0 ;
    	char z ; 
    	char *temp ;
    	temp = calloc( 30, sizeof( char ) ) ;
    	/* Reads in the words one at a time to an array */
    	while( ( z = fgetc( text ) ) != EOF )
    		if( ( ( 65 <= z ) && ( z <= 90 ) ) || ( (  97 <= z ) && ( z <= 122 ) ) || ( z == 45 ) || ( z == 39 ) )
    		{
    			temp[i] = z ;
    			temp[i] = toupper( temp[i] ) ;
    			i++ ; 
    		}
    		else if( strlen( temp ) > 0 && i != 0 ) 
    		{	
    			temp[i]= '\0' ;
    			temp = realloc( temp, i*sizeof( char ) ) ;
    			i = 0 ;
    			printf( "%s %d\n", temp, strlen(temp) ) ;
    		}
    }
    Is my function.

    Depending on the word it reads in from the text file it could be anything from 1 - 15ish
    Last edited by killpoppop; 01-13-2009 at 09:52 AM.

  7. #7
    Registered User
    Join Date
    Nov 2008
    Posts
    44
    Although using 'i' would be smart can i just use 1?

  8. #8
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    Assuming you did call malloc or calloc initially and just didn't show it here...

    Your problem is that you set temp[i] to '\0', but when you realloc i*sizeof(char) bytes, that doesn't include the null terminator, and because realloc usually allocates an entirely new block, and copies the data of the old one over, the next item after the end of temp could be anything, and you're probably hitting some bad buffer overflow on the printf call and the strlen call within it. You need to be reallocing (i+1)*sizeof(char).
    Code:
    void function(void)
     {
      function();
     }

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Incidentally, I double checked and I think I confused realloc()'s behaviour with a smaller resize with something from C++. The C standard does not seem to forbid resizing to a smaller size with realloc().

    Now, have you implemented Jaken Veina's suggestion to account for the null terminator?

    By the way, z should be an int, not a char, since the return value of fgetc() is an int. You should be using isalpha() and character literals instead of magic numbers.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by killpoppop View Post
    Code:
    			temp[i]= '\0' ;
    			temp = realloc( temp, i*sizeof( char ) ) ;
    If i=10, you have just set the eleventh character of temp. But then you realloc it only ten bytes of space. You need:
    Code:
    temp = realloc( temp, i*sizeof( char ) +1) ;
    I think the "crash" (presume you mean a segfault) is then actually from the printf.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  11. #11
    Registered User
    Join Date
    Nov 2008
    Posts
    44
    I've tried that =[ It causes my program to crash even sooner than before. With just 'i' it manages 100 words of so then crashes. (i+1) it can only do one word.

  12. #12
    Registered User
    Join Date
    Nov 2008
    Posts
    44
    MK27 i have tried yours. It compiles fine like the other tries. But once again crashes while its printing out.

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Quote Originally Posted by killpoppop
    I've tried that =[ It causes my program to crash even sooner than before. With just 'i' it manages 100 words of so then crashes. (i+1) it can only do one word.
    What exactly did you try? Also, have you considered that your loop is vulnerable to buffer overflow even if you made that correction because it does not check that i is less than the string's maximum size?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    Registered User
    Join Date
    Nov 2008
    Posts
    44
    I tried changing both cases. The first which has (i+1) and the second which has the plus one after.
    In reply to your question, there could be a word longer than 30 characters?

  15. #15
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Quote Originally Posted by killpoppop
    In reply to your question, there could be a word longer than 30 characters?
    Obviously. Since you are using dynamic memory allocation, it would be better to check if i exceeds the current capacity. If it does, you reallocate with say, double the size, and only then do you assign the newly read character to the array. Note that this means you need to track the capacity of the array.

    Now, the code that you current have in the else block should be moved to after the loop. Only when you are done reading what you need to read do you attempt to resize the string to its optimum capacity.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Very quick math question
    By jverkoey in forum A Brief History of Cprogramming.com
    Replies: 8
    Last Post: 10-26-2005, 11:05 PM
  2. very quick question.
    By Unregistered in forum C++ Programming
    Replies: 7
    Last Post: 07-24-2002, 03:48 AM
  3. quick question
    By Unregistered in forum C++ Programming
    Replies: 5
    Last Post: 07-22-2002, 04:44 AM
  4. Quick Question Regarding Pointers
    By charash in forum C++ Programming
    Replies: 4
    Last Post: 05-04-2002, 11:04 AM
  5. Quick question: exit();
    By Cheeze-It in forum C Programming
    Replies: 6
    Last Post: 08-15-2001, 05:46 PM