Thread: Dynamic memory in C

  1. #1
    Registered User
    Join Date
    Mar 2011
    Location
    Windsor, Ontario
    Posts
    44

    Dynamic memory in C

    Did some reading, but I can't grasp the concepts. I realize that you need to use malloc() on a new pointer but I get confused in the transitions to functions. I could really use any help. Any advice on how I am doing this wrong?
    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
    };
    
    int isEmptyList(struct point *ptrF);
    void PrintList(struct point *ptrF);
    void ResetList(struct point *ptrF, struct point *ptrL);
    void AddToBeginning(struct point *ptrF, struct point *ptrL);
    void AddToEnd(struct point *ptrF, struct point *ptrL);
    void InputRecord(struct point *ptrNew); // 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)
    {
    	struct point *pC = ptrF;
    	while(pC != NULL)
       {
    		printf("Label: %s\nx: %d y:%d\n", pC->label, pC->x, pC->y);
    		pC = pC->ptrNext;  // this is how a list is traversed
       }	
    }
    //reset list will make everything equal to NULL
    void ResetList(struct point *ptrF, struct point *ptrL)
    {
    	free(ptrF);
    	free(ptrL);
    }
    //addtobeginning will add a number to the beginning
    void AddToBeginning(struct point *ptrF, struct point *ptrL)
    {
    	struct point ptrNew;
    	if(ptrF==NULL)
             *ptrF=ptrNew;
    	InputRecord(&ptrNew);
    	ptrNew.ptrNext=ptrF;
    	ptrF=&ptrNew;
    }
    //addtoend will add a number to the end
    void AddToEnd(struct point *ptrF, struct point *ptrL)
    {
    	struct point ptrNew;
    	if(ptrF==NULL)
    		*ptrF = ptrNew;
    	else
    	{
    		InputRecord(&ptrNew);
    		ptrL=&ptrNew;
    	}	
    }
    //reads in input
    void InputRecord(struct point *ptrNew)
    {
    	printf("Please enter the 2 Data points(x and y):\n");
    	ptrFirst=ptrNew;
    	if(ptrNew==NULL)
    		printf("No more memory.\n");	
    	scanf("%d%d",ptrFirst->x, ptrFirst->y);	
    	printf("Please enter the label:\n");
    	scanf("%s", ptrFirst->label);
    	ptrFirst->ptrNext=NULL;
    }
    
    struct point *ptrFirst = NULL;
    struct point *ptrLast = NULL;
    struct point *ptrNew = NULL;
    
    void main()
    {
    	int empty=0;//helps determine if list is empty
    	int input=1;//reads in user input
    	while(input!=0)
    	{
    		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);
    		if(input==1)
    		{
    			ptrNew=(struct point *)(malloc(sizeof(struct point)));
    			AddToEnd(ptrFirst,ptrLast);
    		}
    		if(input==2)
    		{
    			ptrNew=(struct point *)(malloc(sizeof(struct point)));
    			AddToBeginning(ptrFirst,ptrLast);
    		}
    		if(input==3)
    		{
    			ptrNew=(struct point *)(malloc(sizeof(struct point)));
    			empty=isEmptyList(ptrFirst);
    			if(empty==1)
    			{
    				printf("The list is not empty\n\n");
    			}
    			else
    			{
    				printf("The list is empty\n\n");
    			}
    		}
    		if(input==4)
    		{
    			ptrNew=(struct point *)(malloc(sizeof(struct point)));
    			ResetList(ptrFirst,ptrLast);
    		}
    		if(input==5)
    		{
    			ptrNew=(struct point *)(malloc(sizeof(struct point)));
    			PrintList(ptrFirst);
    		}
    		if(input==6)
    		{
    		}
    		if(input==7)
    		{
    		}
    		if(input==0)
    		{
    			input=0;
    		}
    		if(input<0)
    			printf("Invalid entry, try again\n\n");
    		if(input>7)	
    			printf("Invalid entry, try again\n\n");
    	}
    }
    It segmentation faults when scanning in the x and y values.
    Last edited by JamesD; 03-12-2011 at 10:05 PM.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    foo->thing gives you the value of thing. You still need a pointer to thing (its address) if you are going to try to scanf into it, just like if it was an actual int:
    Code:
    scanf( "%d", &myint );
    /* or */
    scanf( "%d", &foo->thing );
    The first part is just saying "I'm accessing something through a pointer to a function that contains..." thing.


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

  3. #3
    Registered User
    Join Date
    Mar 2011
    Location
    Windsor, Ontario
    Posts
    44
    I spent forever trying to solve that, not sure how I never tried that. It is telling me that ptrFirst is undefined inside of InputRecord even though I have it declared globally, Why is that happening? Thanks for the & too.
    Last edited by JamesD; 03-12-2011 at 10:37 PM.

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    void InputRecord(struct point *ptrNew)
    {
    	printf("Please enter the 2 Data points(x and y):\n");
    	ptrFirst=ptrNew;
    	if(ptrNew==NULL)
    		printf("No more memory.\n");	
    	scanf("%d%d",ptrFirst->x, ptrFirst->y);	
    	printf("Please enter the label:\n");
    	scanf("%s", ptrFirst->label);
    	ptrFirst->ptrNext=NULL;
    }
    
    struct point *ptrFirst = NULL;
    struct point *ptrLast = NULL;
    struct point *ptrNew = NULL;
    Because this comes before that in your program, so this doesn't know anything about that.

    Your files in C are handled top to bottom by the compiler. Line 1 knows nothing of line 2. That's why you prototype functions at the top of a file, and write them at the bottom. That's also why you generally declare all of your variables at the top of the file, function, or block, so everything from that point on knows about them.


    Quzah.
    Last edited by quzah; 03-12-2011 at 10:42 PM.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User
    Join Date
    Mar 2011
    Location
    Windsor, Ontario
    Posts
    44
    That problem is solved, however its back to segmenting again, and I do have the & in there now. Any idea what else could be causing this?:
    Code:
    void InputRecord(struct point *ptrNew)
    {
    	printf("Please enter the 2 Data points(x and y):\n");
    	ptrFirst=ptrNew;
    	if(ptrNew==NULL)
    		printf("No more memory.\n");	
    	scanf("%d%d",&ptrFirst->x, &ptrFirst->y);	
    	printf("Please enter the label:\n");
    	scanf("%s", ptrFirst->label);
    	ptrFirst->ptrNext=NULL;
    }

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by JamesD View Post
    That problem is solved, however its back to segmenting again, and I do have the & in there now. Any idea what else could be causing this?:
    Code:
    void InputRecord(struct point *ptrNew)
    {
    	printf("Please enter the 2 Data points(x and y):\n");
    	ptrFirst=ptrNew;
    	if(ptrNew==NULL)
    		printf("No more memory.\n");	
    	scanf("%d%d",&ptrFirst->x, &ptrFirst->y);	
    	printf("Please enter the label:\n");
    	scanf("%s", ptrFirst->label);
    	ptrFirst->ptrNext=NULL;
    }
    Well, you check to see if you ran out of memory (have a null pointer) but you go ahead and use it anyway. You should be doing something like:
    Code:
    void InputRecord(struct point *ptrNew)
    {
        if( ptrNew != NULL )
        {
            ...ok
        }
        else
        {
            error...
        }
    }
    Quzah.
    Hope is the first step on the road to disappointment.

  7. #7
    Registered User
    Join Date
    Mar 2011
    Location
    Windsor, Ontario
    Posts
    44
    Yea, I meant to get that done, here it is:
    Code:
    void InputRecord(struct point *ptrNew)
    {
    	printf("Please enter the 2 Data points(x and y):\n");
    	ptrFirst=ptrNew;
    	if(ptrNew==NULL)
    		printf("No more memory.\n");
    	else
    	{
    	scanf("%d%d",&ptrFirst->x, &ptrFirst->y);	
    	printf("Please enter the label:\n");
    	scanf("%s", ptrFirst->label);
    	ptrFirst->ptrNext=NULL;
    	}
    }
    Its still segmenting though, I looked it over again, but being new to it still came up blank, any professional advice?

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    At what point? What's the last line you are getting before it segfaults? You also have a function's argument named the same thing as your global. I'm also not sure that you mean to be overwriting your list with your new node without keeping track of what's there already. Your function to empty a list doesn't. It just causes a memory leak.


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

  9. #9
    Registered User
    Join Date
    Mar 2011
    Location
    Windsor, Ontario
    Posts
    44
    It segements when I try to enter a number for input inside main, and sorry about the horrible coding... I really have a lot to learn.
    It prints out the menu and I enter the number for the list it will segment only if I enter a 1 or 2. So its a problem within AddtoBeginning, AddtoEnd or InputRecord.

  10. #10
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    void AddToBeginning(struct point *ptrF, struct point *ptrL)
    {
    	struct point ptrNew;
    	if(ptrF==NULL)
             *ptrF=ptrNew;
    	InputRecord(&ptrNew);
    	ptrNew.ptrNext=ptrF;
    	ptrF=&ptrNew;
    }
    //addtoend will add a number to the end
    void AddToEnd(struct point *ptrF, struct point *ptrL)
    {
    	struct point ptrNew;
    	if(ptrF==NULL)
    		*ptrF = ptrNew;
    	else
    	{
    		InputRecord(&ptrNew);
    		ptrL=&ptrNew;
    	}	
    }
    Those aren't pointers. They will be destroyed when the function returns. Also, you keep naming local variables and function arguments the same thing as your globals.

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

  11. #11
    Registered User
    Join Date
    Mar 2011
    Location
    Windsor, Ontario
    Posts
    44
    Took a few mins to look over what you mentioned here is what I came up with:
    Code:
    
    void AddToBeginning(struct point *ptrF, struct point *ptrL)
    {
    	if(ptrF==NULL)
             ptrF=ptrNew;
    	InputRecord(ptrNew);
    	ptrFirst->ptrNext=NULL;
    }
    //addtoend will add a number to the end
    void AddToEnd(struct point *ptrF, struct point *ptrL)
    {
    	if(ptrF==NULL)
    		ptrF = ptrNew;
    	else
    	{
    		InputRecord(ptrNew);
    		ptrL=ptrNew;
    	}	
    }
    //reads in input
    void InputRecord(struct point *ptrNew)
    {
    	printf("Please enter the 2 Data points(x and y):\n");
    	ptrFirst=ptrNew;
    	if(ptrNew==NULL)
    		printf("No more memory.\n");
    	else
    	{
    		scanf("%d%d",&ptrFirst->x, &ptrFirst->y);	
    		printf("Please enter the label:\n");
    		scanf("%s", ptrFirst->label);
    	}
    }
    So it takes in reads and displays correctly, now I have to get ResetList to run.
    Code:
    void ResetList(struct point *ptrF, struct point *ptrL)
    {
    	free(PtrF);
    	free(PtrL);
    }
    I kinda knew going into writing that it would fail, but how do you free a pointer without losing what it points to? and if you free the next you would lose what it points to.. so forth, how do you manage this?
    Last edited by JamesD; 03-12-2011 at 11:49 PM.

  12. #12
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You don't free pointers if you want to keep what they point to. If you want to free a list, you would do something like this:
    Code:
    while pointer is not null
        temp = pointer->next
        free( pointer )
        pointer = temp

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

  13. #13
    Registered User
    Join Date
    Mar 2011
    Location
    Windsor, Ontario
    Posts
    44
    Added temp globally:
    Code:
    struct point *ptrFirst = NULL;
    struct point *ptrLast = NULL;
    struct point *ptrNew = NULL;
    struct point *temp=NULL;
    Modified the function to this:
    Code:
    void ResetList(struct point *ptrF, struct point *ptrL)
    {
    	while(ptrF!=NULL)
    	{
    		temp=ptrF->ptrNext;
    		free(ptrF);
    		ptrF=temp;
    	}
    }
    That didn't seem to work though, is ptrF what I should be using?

  14. #14
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Why do you keep making everything global?

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

  15. #15
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    There's also the little matter of a rather nasty memory leak...
    Code:
    if(input==3)
    {
        ptrNew=(struct point *)(malloc(sizeof(struct point)));
        empty=isEmptyList(ptrFirst);
        if(empty==1)
          {
             printf("The list is not empty\n\n");
         }
       else
        {
          printf("The list is empty\n\n");
        }
       }
    if(input==4)
      {
        ptrNew=(struct point *)(malloc(sizeof(struct point)));
        ResetList(ptrFirst,ptrLast);
      }
    if(input==5)
      {
         ptrNew=(struct point *)(malloc(sizeof(struct point)));
         PrintList(ptrFirst);
       }
    You are repeatedly allocating memory to the same pointer and not using it. This will result in an accumulation of unused, reserved memory as the program runs...

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