Thread: Losing addresses after realloc

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

    Losing addresses after realloc

    Hiya, I'm brand new to C so I'm still trying to get my head around what functions etc are available, and the concept of pointers and memory management.

    What I'm trying to do is create an array of strings read from a file, but I'm having a few issues with realloc.

    I read that if you use realloc, there's a possibility that the addresses of the "stuff" will change, problem being that I've already made a bunch of pointers to the original malloc'd stuff.

    Is there any (easy) way to keep my pointers pointing to the right place after realloc? Or should I completely rethink the whole process?

    Here's what I have so far (any tips or corrections would be much appreciated)

    Code:
    FILE *file;
    	char *filetext=NULL, *pfiletext=NULL;
    	char **array=NULL, **pArray=NULL;	
    	int i=0, c=0, j=0, memoryBlock=50;
    	// i = reusable counter for loops 
    	// c = number of elements in array
    	// j = number of characters read from file
    
    	if (!(file = fopen("sample.txt", "r"))) exit(0); //open file
    
    
    	if(!( filetext = calloc(MAXSIZE, sizeof(char)) )) exit(0); 
    
    
    	j=fread(filetext, sizeof(char), MAXSIZE, file);
    	filetext[j]='\0';
    	fclose(file);
    	
    	
    	if(j==0)
    	{
    		puts("Something bad happened :(");
    		exit(0);
    	}
    	
    	if(!(filetext = realloc(filetext, j++))) exit(0);// fix memory for filesize
    	if(!( array = calloc(memoryBlock+1,sizeof(char*)) )) exit(0); // array memory
    
    	//make pointers point at something
    	pfiletext = filetext;
    	pArray = array;
    	
    	while(1)
    	{
    		if(c==0) // First iteration
    		{
    			*pArray = pfiletext;
    			pArray++;
    			c++;
    		}
    		if(c>memoryBlock)
    		{
    			memoryBlock = memoryBlock + 50;
    			if(!(array = realloc(array, 1+((sizeof(char*)*memoryBlock))))) exit(0); // array memory
    			//something needs to go here but I don't know what!!==========================================
    		}
    		if(!(pfiletext = strchr(pfiletext, '\n'))) break;
    		*pfiletext='\0';
    
    		pfiletext=pfiletext++;
    
    		*pArray=pfiletext;
    		pArray++;
    		c++;
    	}
    Last edited by Alison; 03-30-2008 at 08:22 PM.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    It's not clear what you're trying to do with these pointers. Is the realloc only designed to shrink filetext down to its correct size? The realloc at //something needs to go here is going to be a no-op, since you're trying to reallocate a block of (memoryBlock+1) bytes into a block of (memoryBlock+1) bytes; if that fails, we've got bigger problems here. And since I don't know what you're trying to do there, I can't say whether it's the right thing to extend the block or not. But I will say this: the whole point of a buffer, usually, is to be a fixed size; you read in a bunch o' bytes, process them completely, and then read in a new block to overwrite the old block. So if you don't need the old characters in the next while loop, don't realloc, just overwrite them.

  3. #3
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    In general you should not keep pointers which point into a block of memory that might be realloc()'d. If you need to refer to positions in a reallocatable buffer, use indexes instead of pointers.

  4. #4
    Registered User
    Join Date
    Mar 2008
    Posts
    4
    Hiya, thanks for the quick reply.

    What I'm trying to do is store every line of text into an array so I can call back any line at any time, but since I don't know how many lines of text there could be, I want to be able to extend the size of the memory block after it reaches its limit.

    @brewbuck: Sorry, I don't have the faintest idea what indexes are (remember I'm new to programming!)... would you mind elaborating a bit? Thanks.
    Last edited by Alison; 03-30-2008 at 08:43 PM.

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    All of a sudden we're talking about "lines"? The notion of lines of text is incompatible with using fread. I would look into a line-based method of input, such as fgets.

    But the idea here I think would be to have an "array" of pointers (not a real array, obviously, if we need to resize it). You can calloc storage for a bunch of char *; read in a line and put it somewhere; and set not_really_an_array[count] to point at that line you just read in. If you get more lines than you expected, you can realloc the char * "array" without moving the "real" data.

  6. #6
    Registered User
    Join Date
    Mar 2008
    Posts
    4
    Thank you for your help.

    I'm still interested in this indexing thing though. Supposing I wanted to extract comma separated values or something like that?

    PS: You just made me notice something incredibly silly haha... I AM resizing the "array" of pointers, and not the place where the real stuff is. So I guess my problem isn't actually ever going to be a problem?

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by Alison View Post
    Thank you for your help.

    I'm still interested in this indexing thing though. Supposing I wanted to extract comma separated values or something like that?
    That wouldn't have anything to do with indexing, really. Indexing is just the [i] bit that tells you how far to go from the starting point in an "array" (so in memoryBlock, memoryBlock[0] is the first character, memoryBlock[1] is the next, memoryBlock[2] is the next, etc.).

    If you do want something like CSV, you should look into strtok.

  8. #8
    Registered User
    Join Date
    Mar 2008
    Posts
    4
    Thank you so much for your help It's really useful having a place to bounce ideas!

    I added this to the "something needs to go here":
    pArray=array+c;

    And now it's all fine.

    I'll definitely read up on strtok. Thanks again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Numeric addresses for computers
    By great in forum C Programming
    Replies: 4
    Last Post: 08-23-2010, 11:53 AM
  2. did i understood right this explantion of realloc..
    By transgalactic2 in forum C Programming
    Replies: 3
    Last Post: 10-24-2008, 07:26 AM
  3. writing a pack-style function, any advices?
    By isaac_s in forum C Programming
    Replies: 10
    Last Post: 07-08-2006, 08:09 PM
  4. using realloc
    By bobthebullet990 in forum C Programming
    Replies: 14
    Last Post: 12-06-2005, 05:00 PM