Thread: Why does realloc cause a segfault here?

  1. #1
    Registered User
    Join Date
    Jun 2008
    Posts
    54

    Why does realloc cause a segfault here?

    I'm looking at this code, but I can't seem to figure out why it's segfaulting.
    The purpose of the function is to put each period separated word (token) into a list that grows as large as necessary.
    [Edit: Oh, uh, this is C89.]
    Code:
    #include <stdlib.h>
    static int getdots(char* input, char** keylist) {
    	keylist = calloc(1, sizeof(char*));
    
    	int i = 0;
    	keylist[i] = malloc(512* sizeof (char));
    	memset(keylist[i],'\0', 512*sizeof(char));
    	char* p = input, *c=keylist[0];
    	while (*p!='\0') {
    
    		while(c && p)
    		if(*p!='.')
    		*c++=*p++;
    		else
    		break;
    
    		if(*p=='.')
    		{
    
    			i++;
    			keylist=realloc(keylist, sizeof(char*)*(i+1));
    			keylist[i]=malloc(512*sizeof(char));
    			c=keylist[i];
    			memset(keylist[i],'\0', 512*sizeof(char));
    		}
    		p++;
    	}
    	return 0;
    }
    
    int main() {
    
    	char input[512] = { "hello.helm.happy\0" };
    	char** keylist = NULL;
    	getdots((char*) &input, keylist);
    	if (!keylist) {
    		printf("Nothing happened!\r\n");
    		return 0;
    	}
    	int i = 0;
    	for (i = 0; keylist[i]; i++)
    		printf("%s\r\n", keylist[i]);
    	if (keylist != NULL)
    		free(keylist);
    	return 0;
    
    }
    Last edited by Boxknife; 05-06-2009 at 04:13 PM.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    while(c && p)
    The chances of these actually pointing to NULL are very slim. You should be checking to see that you don't run past your line length, or that they contain '\0'. A pointer pointing at a character containing '\0' will pass a NULL check.
    Code:
    #include<stdio.h>
    int main( void )
    {
        char c = '\0';
        char *p = &c;
    
        if( p )
        {
            printf( "Not null.\n" );
        }
    
        return 0;
    }
    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Jun 2008
    Posts
    54

    Fixed program

    It's now working.
    For whatever it's worth, here is the fixed program:
    Code:
    #include <stdlib.h>
    #include <ctype.h>
    #include <stdio.h>
    #include <string.h>
    #define LOWER(c)   (((c)>='A'  && (c) <= 'Z') ? ((c)+('a'-'A')) : (c))
    static char** getdots(char* input, char** keylist) {
    
    	int i=0;
    	keylist[i]=malloc(512*sizeof(char));
    	memset(keylist[i],'\0', 512*sizeof(char));
    	char* p = input, *c=keylist[i];
    	while (*p!='\0') {
    
    		while(*p!='.' && *p!='\0')
    		*c++=*p++;
    
    		if(*p=='\0')
    		{
    		
    		return keylist;
    		}
    		if(*p=='.')
    		{
    		i++;
    		keylist= realloc(keylist, sizeof(char*)*(i+1));
    		if(!keylist){
    		printf("Keylist broken.\r\n");
    		return NULL;
    		}
    		keylist[i]=malloc(512*sizeof(char));
    		c=keylist[i];
    		memset(keylist[i],'\0', 512*sizeof(char));
    		}
    		p++;
    	}
    	return keylist;
    }
    
    int isname(const char *str, const char *namelist) {
    	const char *curname, *curstr;
    	curname = namelist;
    	for (;;) {
    		for (curstr = str;; curstr++, curname++) {
    			if (!*curstr && !isalpha(*curname))
    				return (1);
    
    			if (!*curname)
    				return (0);
    
    			if (!*curstr || *curname == ' ' || *curname == '-' || *curname == ',')
    				break;
    
    			if (LOWER(*curstr) != LOWER(*curname))
    				break;
    		}
    
    		/* skip to next name */
    
    		for (;isalpha(*curname); curname++)
    			;
    		if (!*curname)
    			return (0);
    		curname++; /* first char of new name */
    	}
    }
    
    
    int main()
    {
    
    char input[512]={"big.r.helm.yay\0"};
    char sdesc[512]={"a big, red helm\0"};
    char** keylist=NULL;
    keylist=calloc(1,sizeof(char*));
    
    keylist=getdots((char*) &input, keylist);
    if(!keylist)
    {
    printf("Nothing happened!\r\n");
    return 0;
    }
    int i=0;
    for(i=0;keylist[i];i++)
    {
    printf("%s\r\n",keylist[i]);
    if(isname(keylist[i], sdesc))
    printf("%s is in the list.\r\n", keylist[i]);
    else
    printf("%s is not in the list.\r\n", keylist[i]);
    }
    
    if(keylist)
    free(keylist);
    
    return 0;
    
    
    
    
    }
    Last edited by Boxknife; 05-06-2009 at 07:41 PM.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Indentation needs work, and there's still a couple of bugs....
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. did i understood right this explantion of realloc..
    By transgalactic2 in forum C Programming
    Replies: 3
    Last Post: 10-24-2008, 07:26 AM
  2. malloc() resulting in a SegFault?!
    By cipher82 in forum C++ Programming
    Replies: 21
    Last Post: 09-18-2008, 11:24 AM
  3. using realloc
    By bobthebullet990 in forum C Programming
    Replies: 14
    Last Post: 12-06-2005, 05:00 PM
  4. segfault on realloc
    By ziel in forum C Programming
    Replies: 5
    Last Post: 03-16-2003, 04:40 PM
  5. Realloc inappropriate for aligned blocks - Alternatives?
    By zeckensack in forum C Programming
    Replies: 2
    Last Post: 03-20-2002, 02:10 PM