Thread: Dynamic memory in C

  1. #31
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Well, you still have the same problem of calling all of your arguments the same things as your global variables. But, if you were to do it without recursion, and with correctly passing it the start of your list, it would look something like this:
    Code:
    void printlist( struct list *l )
    {
        while l is not null
            print contents of l
            l = l->next
    }
    Quzah.
    Hope is the first step on the road to disappointment.

  2. #32
    Registered User
    Join Date
    Mar 2011
    Location
    Windsor, Ontario
    Posts
    44
    Right, I understand that and made this:
    Code:
    void PrintList(struct point *ptrF)
    {
    	while(ptrF != NULL)
       {
    		printf("Label: %s\nx: %d y:%d\n\n", ptrF->label, ptrF->x, ptrF->y);
    		ptrF = ptrF->ptrNext;  // this is how a list is traversed
       }
    }
    and I KNOW it makes it through inputrecord because it scans in those values:
    Code:
    struct point *InputRecord (void)
    {
    	struct point *ptrN=malloc(sizeof(struct point));
    	if(ptrN==NULL)
    	{
    		printf("No more memory.\n");
    		exit(1);
    	}
    	printf("Please enter the 2 Data points(x and y):\n");
        scanf("%d%d",&ptrN->x, &ptrN->y);	
        printf("Please enter the label:\n");
        scanf("%s", ptrN->label);
        return ptrN;                         // return pointer to new struct	
    }
    so it must fail in addtobeginning because when I put a flag in printlist it will not enter because it finds the first to be null:
    Code:
    void AddToBeginning(struct point *ptrF, struct point *ptrL)
    {	
    	struct point *temp = ptrFirst;                   // save pointer to first record
        ptrF = InputRecord();                     // get pointer to new first record
    	ptrF->ptrNext = temp;
    }
    If I assume its a problem with the first and last lines, but if thats right what should I change on them?

  3. #33
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You can't change what a pointer points at inside a function and have it keep outside the function, unless you are using a pointer to a pointer. Also, your constant use of variables named the same thing as globals isn't doing you any favors. (It's not doing ME any, anyway.) Your AddToBeginning should just be:
    Code:
    void ATB( node *n )
    {
        n->next = globalfirstpointer;
        globalfirstpointer = n;
    }
    That's all. Then your input function should just be something that sticks input in a node:
    Code:
    void inp( node *n )
    {
        if( n )
        {
            ...scanf a bunch of stuff
        }
    }
    Linked list functions typically do just one specific task. You don't generally mix them up so they do a bunch of things at the same time.


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

  4. #34
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Yet another reason global variables are BAD....
    Code:
    void AddToBeginning(struct point *ptrF)
    {	
        struct point *temp = ptrF;    // save pointer to first record
        ptrF = InputRecord();                     // get pointer to new first record
        ptrF->ptrNext = temp;
    }
    And you don't need ptrL in that function...

    Quote Originally Posted by JamesD View Post
    Right, I understand that and made this:
    Code:
    void PrintList(struct point *ptrF)
    {
    	while(ptrF != NULL)
       {
    		printf("Label: %s\nx: %d y:%d\n\n", ptrF->label, ptrF->x, ptrF->y);
    		ptrF = ptrF->ptrNext;  // this is how a list is traversed
       }
    }
    You are trashing your pointer to the first record... think where it will be when the loop exits.

    Code:
    void PrintList(struct point *ptrF)
    {  struct point *pp = ptrf;           // protect first record pointer
        while(pp != NULL)
       {
          printf("Label: %s\tX: %d Y:%d\n", pp->label, pp->x, pp->y);
         pp = pp->ptrNext; 
       }
    }
    Just as some general advice... you need to stop making 30 changes at a time. Make 1 (one) change and test it... if it doesn't work... put it back the way it was. Really, you don't have to rewrite half the program because you're having a problem with one or two lines of code...
    Last edited by CommonTater; 03-14-2011 at 11:41 PM.

  5. #35
    Registered User
    Join Date
    Mar 2011
    Location
    Windsor, Ontario
    Posts
    44
    Attempted to re-write the functions to avoid the whole global problem and using case 1 got:
    Declared in main:
    struct point *ptr=NULL;
    Code:
    case 1:
    {
    	ptr=InputRecord();
    	AddToEnd(ptr);
    	break;
    }
    Code:
    struct point *InputRecord (void)
    {
    	struct point *ptrN=malloc(sizeof(struct point));
    	if(ptrN==NULL)
    	{
    		printf("No more memory.\n");
    		exit(1);
    	}
    	printf("Please enter the 2 Data points(x and y):\n");
        scanf("%d%d",&ptrN->x, &ptrN->y);	
        printf("Please enter the label:\n");
        scanf("%s", ptrN->label);
        return ptrN;                         // return pointer to new struct	
    }
    Code:
    void AddToEnd(struct point *ptrN)
    {
    	if(ptrFirst==NULL)
    		ptrFirst=ptrN;
    	ptrLast->ptrNext=ptrN;
    	ptrN->ptrNext=NULL;
    	ptrLast=ptrN;
    }
    Code:
    void PrintList(struct point *ptrF)
    {
    	while(ptrF != NULL)
       {
    		printf("Label: %s\nx: %d y:%d\n\n", ptrF->label, ptrF->x, ptrF->y);
    		ptrF = ptrF->ptrNext;  // this is how a list is traversed
       }	
    }
    Note I still kept these global but I think it helps avoid the problem, they still don't work, just thought I would try that to get rid of the global thing, and make it easier to work with. I tried anyway..
    struct point *ptrFirst = NULL;
    struct point *ptrLast = NULL;

  6. #36
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You will want to check that ptrLast isn't NULL before you use ->next, in addlast. You'll need to post the full thing if you're getting errors/problems again, since you're changing so much.


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

  7. #37
    Registered User
    Join Date
    Mar 2011
    Location
    Windsor, Ontario
    Posts
    44
    Here it is:
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    
    struct point
    {
    	int x; //point x
    	int y; //point y
    	char label[21]; //label of 2 points
    	struct point *ptrNext;	// self referential pointer
    };
    
    struct point *ptrFirst = NULL;
    struct point *ptrLast = NULL;
    
    int isEmptyList(struct point *ptrF);
    void PrintList(struct point *ptrF);
    void ResetList(struct point *ptrF, struct point *ptrL);
    void AddToBeginning(struct point *ptrF);
    void AddToEnd(struct point *ptrN);
    struct point *InputRecord( void ); // used by Add to interactively get the values from the user
    int isEmptyList(struct point *ptrF)//emptylist will determine if the list is empty
    {
       {
    		if(ptrF==NULL)
    		{
    			return 0;
    		}
    		else
    			return 1;
       }
    }
    //print list will print out everything
    void PrintList(struct point *ptrF)
    {
    	while(ptrF != NULL)
       {
    		printf("Label: %s\nx: %d y:%d\n\n", ptrF->label, ptrF->x, ptrF->y);
    		ptrF = ptrF->ptrNext;  // this is how a list is traversed
       }	
    }
    //reset list will make everything equal to NULL
    void ResetList(struct point *ptrF, struct point *ptrL)
    {
    	struct point *temp=ptrF;
    	while(temp!=NULL)
    	{
    		ptrF=ptrF->ptrNext;
    		free(temp);
    		temp=ptrF;
    	}
    }
    //addtobeginning will add a number to the beginning
    void AddToBeginning(struct point *ptrF)
    {	
    	ptrF->ptrNext=ptrFirst;
    	ptrFirst=ptrF;
    }
    //addtoend will add a number to the end
    void AddToEnd(struct point *ptrN)
    {
    	if(ptrFirst==NULL)
    		ptrFirst=ptrN;
    	ptrLast->ptrNext=ptrN;
    	if(ptrLast!=NULL)
    	{
    		ptrN->ptrNext=NULL;
    		ptrLast=ptrN;
    	}	
    }
    //reads in input
    struct point *InputRecord (void)
    {
    	struct point *ptrN=malloc(sizeof(struct point));
    	if(ptrN==NULL)
    	{
    		printf("No more memory.\n");
    		exit(1);
    	}
    	printf("Please enter the 2 Data points(x and y):\n");
        scanf("%d%d",&ptrN->x, &ptrN->y);	
        printf("Please enter the label:\n");
        scanf("%s", ptrN->label);
        return ptrN;                         // return pointer to new struct	
    }
    
    int main()
    {
    	int empty=0;//helps determine if list is empty
    	int input=1;//reads in user input
    	struct point *ptr=NULL;
    	while(1)
    	{
    		printf(
    		"1. Add a point at the END of the list.\n"
    		"2. Add a point at the BEGINNING of the list.\n"
    		"3. Is the list empty?\n"
    		"4. Erase all points from the list (reset).\n"
    		"5. Display the list.\n"
    		"6. Save the list to a sequential file (reset/replace file contents)\n"
    		"7. Read the list back from a sequential file\n" 
    		"(reset/replace current memory content)\n"
    		"0. Exit\n\n"
    		);
    		scanf("%d", &input);
    		switch(input)
    		{
    			case 0:
    			{
    				return 0;
    				break;
    			}
    			case 1:
    			{
    				ptr=InputRecord();
    				AddToEnd(ptr);
    				break;
    			}	
    			case 2:
    			{
    				AddToBeginning(ptrFirst);
    				break;
    			}
    			case 3:
    			{
    				empty=isEmptyList(ptrFirst);
    				if(empty==1)
    				{
    					printf("The list is not empty\n\n");
    				}	
    				else
    				{
    					printf("The list is empty\n\n");
    				}
    				break;
    			}
    			case 4:
    			{
    				ResetList(ptrFirst,ptrLast);
    				break;
    			}
    			case 5:
    			{
    				PrintList(ptrFirst);
    				break;
    			}
    			case 6:
    			{
    				break;
    			}
    			case 7:
    			{
    				break;
    			}
    			default:
    			{
    				printf("Invalid entry, try again\n\n");
    				break;
    			}
    		}
    	}
    }

  8. #38
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    When you add to the front or tail, you should check to see if it's empty, and fix both pointers at that time.
    Code:
    void add(x)
        if isempty
            front = last = x
        else
            ...

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

  9. #39
    Registered User
    Join Date
    Mar 2011
    Location
    Windsor, Ontario
    Posts
    44
    Ok, I got it compiled now, it will run and accept 1 list, I added what you mentioned:
    Code:
    void AddToEnd(struct point *ptrN)
    {
    	if(ptrFirst==NULL)
    		ptrFirst=ptrN;
    		ptrLast=ptrN;
    	ptrLast->ptrNext=ptrN;
    	if(ptrLast!=NULL)
    	{
    		ptrN->ptrNext=NULL;
    		ptrLast=ptrN;
    	}	
    }
    It however will only hold 1 list at a time while printing. I won't be able to check on until tomorrow morning but will work on it again then.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. [BEGINNER] dynamic memory dumb question
    By arthurhess in forum C++ Programming
    Replies: 2
    Last Post: 12-14-2009, 02:53 PM
  2. Dynamic Linking & Memory usage
    By @nthony in forum C Programming
    Replies: 2
    Last Post: 06-02-2007, 09:57 PM
  3. Dynamic memory allocation...
    By dicorr in forum C Programming
    Replies: 1
    Last Post: 06-24-2006, 03:59 AM
  4. Is it necessary to write a specific memory manager ?
    By Morglum in forum Game Programming
    Replies: 18
    Last Post: 07-01-2002, 01:41 PM
  5. Dynamic Memory Allocation for fstream (binary)
    By kuphryn in forum C++ Programming
    Replies: 2
    Last Post: 12-12-2001, 10:52 AM