Thread: Function for getting configuration causes segfault

  1. #1
    Registered User
    Join Date
    May 2011
    Posts
    23

    Question Function for getting configuration causes segfault

    I'm sort of a self-taught beginner programmer here. One thing I always tried to avoid was pointers. After this last project, I figured I had to start learning them, as well as improving what other skills I might have.

    This program is supposed to read a line from a configuration file and pass it back to whatever requests it, be it a variable or another function. It always causes a segfault.

    It's probably something stupidly simple that I'm overlooking here, but I'm really new to these things. Any help would be greatly appreciated!

    Code:
    int main()
    {
    	char *blah;
    
    	blah = getconf(false,"test");
    
    	printf("%s\n",blah);
    
    	return(0);
    }
    
    char *getconf(bool writelog,char get[])
    {
    	char line[256];
    	FILE *config;
    	int a = 0;
    	char setting[25];
    	char *value;
    	
    	config = fopen("test.conf","r");
    	
    	while(fgets(line,sizeof(line),config) != NULL) {
    		a++;
    		
    		if(line[0] == '#') continue; //If the line is a comment, skip it
    		if(sscanf(line,"%s = %s",setting,value) != 2) {
    			if(writelog == true) {
    				printf("%i: syntax error!\n",a);
    			}
    			continue;
    		}
    		puts("return if");
    		if(strcmp(setting,get)) return(value); //GDB backtrace always shows the segfault around this area.
    		puts("val not found");
    	}
    
    	if(writelog == true) {
    		printf("%s: value not found\n",get);
    	}
    	
    	return("no value");
    }

  2. #2
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Code:
    char *value;
    You have a pointer which does not point to any memory. Instant segfault.

  3. #3
    Registered User
    Join Date
    May 2011
    Posts
    23
    I see. But why does
    Code:
    char *blah;
    work in main?

  4. #4
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by screennameless View Post
    I see. But why does
    Code:
    char *blah;
    work in main?
    Dumb luck... Really... just plain old fashioned dumb luck.

    In your getconf function you are making two crucial mistakes...
    1) you are creating a pointer ... char *value... that points to literally nothing... then with no attempt at initialization you copy a string to it with sscanf().
    2) When you return from that function, you are returning a pointer to value, which then goes out of scope and is destroyed when the function exits.

    It *appears* to work in main because the error occurs duing the function call on the right side of the equals, never reaching the assignment to blah... which would almost certainly segfault as well.

    There's no magic here... If you're going to create a pointer A) it has to point to *something*, B) it has to stay in scope until you're done with it, C) if you've allocated memory, you have to free it when done.

    Do some searching in the forums here... there have been many discussions of returning pointers to arrays from functions... mostly ending up in lots and lots of reasons why that is a singularly bad idea.
    Last edited by CommonTater; 05-08-2011 at 10:39 AM.

  5. #5
    Registered User
    Join Date
    May 2011
    Posts
    23
    Thanks for your reply!
    Would my pointers have to point to a char array? Or should I use malloc()?

    These things always confuse me, no matter how many tutorials I read...

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by screennameless View Post
    Thanks for your reply!
    Would my pointers have to point to a char array? Or should I use malloc()?

    These things always confuse me, no matter how many tutorials I read...
    Either way is fine. If you are prompting them for the size of the input, then you could malloc that space. If you are working with a fixed space, an array is fine. It really just depends on whatever you feel like doing.


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

  7. #7
    Registered User
    Join Date
    May 2011
    Posts
    23
    Now, when you say prompting for the size of the input, does that mean I can wait and allocate based on how big the final variable needs to be?

    For example, getconf gets a setting which equals "asdf", could I have it allocate so it *just* fits "asdf"? But then if it gets another setting which equals "something", it allocates to fit "something"?

    If so, then that solves the #1 problem I have with C: having to know the maximum size of variables before the program even runs.

  8. #8
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Well if you read in the line, and it's not a comment, then apparently the format is
    Code:
    name = value
    . That line is read into your temporary buffer named line. You can then find the = sign and determine the length of the value string based on the length from that = to the end of the line string, and dynamically allocate your value pointer to the appropriate size and copy it in.

    Don't forget: fgets reads the newline character also into the buffer, so you will need to remove that before you copy the value into the allocated memory.

  9. #9
    Registered User
    Join Date
    May 2011
    Posts
    23
    Okay. So I have the function set to realloc "value" to the size of the string to be returned.

    Back to main; if I declare the pointer as:
    Code:
    char *blah = getconf(false,"test");
    will it automatically allocate the necessary memory? If not, is there some way I can get the size of the returned string before I actually return the string?

  10. #10
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    You don't need to realloc memory. Allocate the memory in the function, return the pointer to the caller, the caller frees the memory when it's done with it.

  11. #11
    Registered User
    Join Date
    May 2011
    Posts
    23
    Okay. The function now is able to read a line from config, and return it to the caller.
    The problem now, is that it always returns the first line of configuration.

    The config file looks like this:
    Code:
    test = abc
    something = somethingelse
    this = that
    I request a line and print it out with:
    Code:
    char *blah = getconf(true,"something");
    For some reason, getconf always returns "abc" -- the first line of the config file -- when it should be equaling "somethingelse", because it's something's value.

    Here is the code I'm working with:
    Code:
    int main()
    {
    	//This isn't the full main function, but it's the part I'm working with
    	char *blah = getconf(true,"something");
    	printf("%s\n",blah);
    	return(0);
    }
    
    char *getconf(bool writelog,char get[])
    {
    	char line[256];
    	FILE *config;
    	int a = 0;
    	char setting[25];
    	char val[150];
    	
    	config = fopen("test.conf","r");
    	
    	while(fgets(line,sizeof(line),config) != NULL) {
    		a++;
    		
    		if(line[0] == '#') continue; //If the line is a comment, skip it
    		if(sscanf(line,"%s = %s",setting,val) != 2) {
    			if(writelog == true) {
    				mlog = fopen("test.log","a");
    				fprintf(mlog,"%s config: %i: syntax error!\n",gettime(),a);
    				fclose(mlog);
    			}
    			continue;
    		}
    		if(strcmp(get,setting)) {
    			char *value = (char*)malloc(strlen(val) * sizeof(char));
    			strcpy(value,val);
    			return(value);
    		}
    	}
    
    	if(writelog == true) {
    		mlog = fopen("test.log","a");
    		fprintf(mlog,"%s config: %s: value not found!\n",gettime(),get);
    		fclose(mlog);
    	}
    	
    	return("no value");
    }
    Thanks again!

  12. #12
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Code:
    if(strcmp(get,setting))
    strcmp returns 0 on a match, as it's measuring the difference between the two strings. 0 is false, your test is for true.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 05-21-2009, 05:50 PM
  2. Getting segfault using member-function pointers
    By dudeomanodude in forum C++ Programming
    Replies: 2
    Last Post: 12-02-2008, 09:56 AM
  3. segfault from linked list function
    By kataya in forum C Programming
    Replies: 7
    Last Post: 04-16-2008, 04:30 AM
  4. Configuration file
    By nbo10 in forum C# Programming
    Replies: 2
    Last Post: 05-18-2004, 09:07 PM
  5. looking for files configuration
    By frigga in forum A Brief History of Cprogramming.com
    Replies: 1
    Last Post: 11-21-2002, 08:55 AM

Tags for this Thread