Thread: Runtime error! Please help

  1. #1
    the Corvetter
    Join Date
    Sep 2001
    Posts
    1,584

    Runtime error! Please help

    Okay, I tried the strcpy function and I tried sprintf. They both compiled with no errors, but then I had a runtime error. I think I tracked the error down to the functions strcpy (the first time) and sprintf (the second time). Here is the code. Tell me if you find the error.
    Code:
    /**************************************************
     ****	A cross-reference program illustrating	****
     ****	the use of linked lists			****
     ***************************************************/
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #define NAMESIZE 50
    
    struct list {
    	char name[NAMESIZE];		/* Holds the name of reference */
    	struct list *next_list;	/* The next reference to name */
    };
    
    /***************************************************
     *	fndnm - searches through the linked list to
     *			find the given name
     *		
     *	parameters - pointer to first struct and name
     *						
     *	return - 0 if null, 1 if found
    ****************************************************/
    int fndnm(struct list *first_list, char *search)
    {
    	struct list *look_list;
    	/* start with the first struct */
    	look_list = first_list;
    
    	while (1)
    	{
    		if (look_list == NULL)
    			return 0;
    		else if (look_list->name == search)
    			return 1;
    		else
    			look_list = look_list->next_list;
    	}
    }
    
    int main()
    {
    	int counter, yesno;
    	struct list *init_list;
    	char line[100];
    
    	for (counter = 0; counter < 5; ++counter)
    	{
    		printf("Enter a name: ");
    		fgets(line, sizeof(line), stdin);
    		line[strlen(line)-1] = '\0';
    		sprintf(init_list->name, "%s", line);
    		/* goto next list */
    		init_list = init_list->next_list;
    	}
    	printf("Now, enter a name to search: ");
    	fgets(line, sizeof(line), stdin);
    	line[strlen(line)-1] = '\0';
    	yesno = fndnm(init_list, line);
    	if (yesno)
    		printf("Found = TRUE");
    	else
    		printf("Found = FALSE");
    	
    	return (0);
    }
    This is it. The first time I tried, I replaced sprintf(init_list->name, "%s", line) with strcpy(init_list->name, line). Thanks.
    1978 Silver Anniversary Corvette

  2. #2
    of Zen Hall zen's Avatar
    Join Date
    Aug 2001
    Posts
    1,007
    You have a pointer to a list structure but you are not allocating any memory to store this list.

    Every time you need a new list you need to do -

    struct list *list_ptr;
    list_ptr = malloc(sizeof (struct list));

    and then when you've finished with it you need to -

    free(list_ptr);

    for each list allocated.

    You will need a pointer to traverse the list. You shouldn't use the pointer to the head of the list (init_list) otherwise you'll no longer be able to access anything before this pointer and you'll get a memory leak. Also, each time you allocate memory for a new list you should set it's next_list pointer to NULL before you attach another list so you can tell which list is the tail.

  3. #3
    the Corvetter
    Join Date
    Sep 2001
    Posts
    1,584
    So, where would I insert the code

    > struct list *list_ptr;

    list_ptr = malloc(sizeof (struct list)); <
    I understand my error here. When you say I should have a pointer to go through the list instead of the head-of-list pointer (init_list), I would just do something like this, right?

    struct list *init_list;
    struct list *walk_list;
    walk_list = init_list;

    And then your other comment, what pointer would I make null? Thanks.
    1978 Silver Anniversary Corvette

  4. #4
    of Zen Hall zen's Avatar
    Join Date
    Aug 2001
    Posts
    1,007
    You want something like this (note-this does no error checking) -

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #define NAMESIZE 50
    
    struct list {
    	char name[NAMESIZE];		/* Holds the name of reference */
    	struct list *next_list;	/* The next reference to name */
    };
    
    int fndnm(struct list *first_list, char *search)
    {
    	struct list *look_list;
    	/* start with the first struct */
    	look_list = first_list;
    
    	while (1)
    	{
    		if (look_list == NULL)
    			return 0;
    		else if (strcmp(look_list->name,search)==0)
    			return 1;
    		else
    			look_list = look_list->next_list;
    	}
    }
    
    void DeleteList(struct list* head)
    {
    	struct list* temp;
    	while(head!=NULL)
    	{
    		temp=head->next_list;
    		free(head);
    		head=temp;
    	}
    }
    		
    int main()
    {
    	int counter, yesno;
    	struct list *init_list,*walk_list;
    	char line[100];
    
    	/*create first list*/
    
    	init_list = malloc(sizeof(struct list));
    
    	walk_list = init_list;
    	for (counter = 0; counter < 5; ++counter)
    	{
    		struct list* temp;
    		printf("Enter a name: ");
    		fgets(line, sizeof(line), stdin);
    		line[strlen(line)-1] = '\0';
    		sprintf(walk_list->name, "%s", line);
    		/* allocate next list */
    		temp=malloc(sizeof(struct list));
    		temp->next_list=NULL;
    		walk_list->next_list=temp;
    		walk_list = temp;
    	}
    	printf("Now, enter a name to search: ");
    	fgets(line, sizeof(line), stdin);
    	line[strlen(line)-1] = '\0';
    	yesno = fndnm(init_list, line);
    	if (yesno)
    		printf("Found = TRUE");
    	else
    		printf("Found = FALSE");
    
    	/*clean up before exit*/
    
    	DeleteList(init_list);
    	
    	return 0;
    }

  5. #5
    the Corvetter
    Join Date
    Sep 2001
    Posts
    1,584
    Thanks! I understand. Except, why do you explicitly free the memory from the allocated structures on the heap? When the computer ends, doesn't it automatically free the memory from the heap? Or is it just a good practice to explicitly free the memory from the heap? Thanks again.
    1978 Silver Anniversary Corvette

  6. #6
    the Corvetter
    Join Date
    Sep 2001
    Posts
    1,584
    Just one more question about your post, zen. On this line of code

    > else if (strcmp(look_list->name,search)==0)

    why can't you just use the boolean comparing type instead of the strcmp function. Why can't you do this

    > else if (look_list->name == search)

    to find out if the value of name in look_list is equal to search? And then this line of code I don't understand

    > sprintf(walk_list->name, "%s", line);

    why can't you just assign line to walk_list->name like this

    > walk_list->name = line;

    to assign the value of line. Is there a reason for this? Is it because that these are linked lists or pointers? Thanks.
    1978 Silver Anniversary Corvette

  7. #7
    Skunkmeister Stoned_Coder's Avatar
    Join Date
    Aug 2001
    Posts
    2,572
    old c style null terminated char* strings are a character array. You cannot assign arrays to each other only elements of arrays.Similarly you cannot compare arrays only single elements. To get around this you can use the functions provided by <string.h> or <cstring>. These functions normally consist of a loop and in the loop they assign consecutive elements of one array to another array or compare elements etc. You can write code that looks like yours but you will have to write your own string class with a full complement of overloaded operators. But even if you do that you will still use the functions in <string.h> to 'power' your operators.

    whoops forget your own string class that is c++ not c.
    Free the weed!! Class B to class C is not good enough!!
    And the FAQ is here :- http://faq.cprogramming.com/cgi-bin/smartfaq.cgi

  8. #8
    of Zen Hall zen's Avatar
    Join Date
    Aug 2001
    Posts
    1,007
    When the computer ends, doesn't it automatically free the memory from the heap? Or is it just a good practice to explicitly free the memory from the heap?
    When the computers shutdown it will, and depending on the o/s memory will normally be released in one way or another when the program finishes, however as this is not guaranteed it's good practice to free any memory you've allocated.

    why can't you just use the boolean comparing type instead of the strcmp function. Why can't you do this
    Because the boolean == will compare memory addresses of strings, not their contents.

    why can't you just assign line to walk_list->name like this > walk_list->name = line;
    Because you would be trying to assign the address of line to walk_list->name; As walk_list->name is not a pointer to char it can't accept this assignment. You need to use strcpy() or sprintf() to copy the contents.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Runtime formation and execution at runtime
    By Soham in forum C Programming
    Replies: 17
    Last Post: 08-27-2008, 08:45 AM
  2. link with C runtime library
    By George2 in forum C++ Programming
    Replies: 26
    Last Post: 02-05-2008, 01:56 AM
  3. Visual Studio and .Net Runtime Framework dependency
    By George2 in forum C# Programming
    Replies: 1
    Last Post: 08-08-2007, 07:52 AM
  4. Change a control class during runtime
    By Joelito in forum Windows Programming
    Replies: 3
    Last Post: 01-12-2006, 02:13 PM
  5. FILES in WinAPI
    By Garfield in forum Windows Programming
    Replies: 46
    Last Post: 10-02-2003, 06:51 PM