Thread: How much memory did I use?

  1. #1
    Registered User
    Join Date
    Feb 2011
    Posts
    96

    How much memory did I use?

    I'm new to C and trying to get my arms around memory allocation.

    1. How much memory do I have allocated (including any/all variables) just before I call free() ?
    2. How much do I have allocated (including any/all variables) after I call free?
    3. When I make strOrig = dest what happens?
    Does it just repoint or reset the value of the original memory?
    What happens to the malloc allocated space?

    Obviously, I'm trying to allocate as little memory as possible, using as little processing as possible. Also, I need to be able to free it when I'm done.
    I'm trying to create a Binary Search Tree in the long run.

    Code:
    char *subStr(char *strOrig, int nStart)
    {
    	static char dest[4096];
    
    	strcpy(dest, strOrig + nStart);
    	strOrig = dest;
    	return strOrig;
    }
    int main()
    {
    	char *buffer = malloc(250);
    	
    	buffer = "http://www.softlinksys.com/Programming/aspnet.php";
    	printf("\nSize: %d %s\n", (int)buffer, buffer);
    	buffer = subStr(buffer, 7);
    	printf("\nSize: %d %s\n", (int)buffer, buffer);
    	free(buffer);	
    	return 0;
    }

  2. #2
    Novice
    Join Date
    Jul 2009
    Posts
    568
    1. On heap you have dest (I think static variables are put on the heap, someone correct me if I'm wrong) and buffer. So that's a total of 4346 bytes, not counting malloc() overhead.

    2. Impossible to tell, as we do not know what happens when you call free() on a pointer that does not point to memory previously malloc()'ed. E.g. it's undefined.

    3. You make strOrig, and by extensions buffer, point to dest. Last and only reference to malloc()'ed memory is lost. You have now created a memory leak.


    In this case, you did not need to malloc() any memory for buffer. String literals that appear in your code are all stored in programs data segment. When you're assigning a string literal to a pointer, you're not making a copy of it and putting it into buffer (you'd need to use strcpy() for that), you're actually assigning the address of literal's first character to the pointer.
    Disclaimer: This post shows my ignorance at the time of its making. I claim ownership of but not responsibility for all errors in it. Reference at your own peril.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Nothing against binary search tree's, but using your files for input, we've dropped the run time down from idk, maybe an hour, to less than half a second, using simple arrays, and a simple binary search (NO tree).

    Arrays and this algorithm will work well in C#, because the improvement is largely due to an improved algorithm.

    Binary search tree's are not easily handled by beginner's in C, since they rely heavily on pointers.

  4. #4
    Registered User
    Join Date
    Feb 2011
    Posts
    96
    OK, I understand a bit better, thanks.

    In the code below, is there any way to deallocate the memory of buff1 after I've copied all but the first 5 characters to buff2?

    Also, is there anything I can do to truncate the allocated memory to only what I need for buff2?

    Code:
    	char buff1[4096]="http://www.softlinksys.com/Programming/aspnet.php";
    	char buff2[4096];	
    	strcpy(buff2, buff1 + 5);
    Last edited by MAtkins; 02-11-2011 at 04:10 AM.

  5. #5
    Registered User
    Join Date
    Feb 2011
    Posts
    96
    Thanks Adak:
    What algorigthm did you use and what did you use for the initial test ('idk, maybe an hour')?

    I could pretty easily encounter a million or even 2 million URLs to sift through.
    As you can see, I'm struggling with pointers now, and that from trying to implement a Binary Tree.

  6. #6
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    1. How much memory do I have allocated (including any/all variables) just before I call free() ?
    ??
    2. How much do I have allocated (including any/all variables) after I call free?
    ??
    3. When I make strOrig = dest what happens?
    strOrig now points to dest.

    Does it just repoint or reset the value of the original memory?
    What happens to the malloc allocated space?
    Question 4.8

    Code:
    	char *buffer = malloc(250);
    	
    	buffer = "http://www.softlinksys.com/Programming/aspnet.php";
    	printf("\nSize: %d %s\n", (int)buffer, buffer);
    You have memory leak here.
    buffer is initially pointing to malloc'd memory.
    Then you make it point to string literal. (now you have no way to access the malloc'd memory block, thus memory leak)
    free(buffer);
    should cause segfault, because at that point. buffer is pointing to static array(static char dest[4096]).

    the correct way is:
    Code:
       char *buffer = malloc( 250 );
       strcpy(buffer,"http://www.softlinksys.com/Programming/aspnet.php");
    Of coz, you've to make sure that you don't copy more than allocated space.
    Last edited by Bayint Naung; 02-11-2011 at 04:51 AM.

  7. #7
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by MAtkins View Post
    Thanks Adak:
    What algorigthm did you use and what did you use for the initial test ('idk, maybe an hour')?

    I could pretty easily encounter a million or even 2 million URLs to sift through.
    As you can see, I'm struggling with pointers now, and that from trying to implement a Binary Tree.
    Oh yes, I know the problem - that's why I advise NOT using a binary tree, use array's instead:

    They're far easier and imo, faster (overall).

    You mentioned "about an hour" in one of your posts, I believe. I didn't test it, because I know from experience, that making 214 comparisons, with 44k (or so) strings, is going to be VERY slow, indeed. One of the first big programs I did in programming, was too correct (by matching records), three files, from different sources within the company I worked at. Using the database software, it took about 15 hours. Using my program, it took 22 minutes. (This was on 286 @ 12 MHz hardware, back in the days).

    I'll post up the code and details, in the original thread on it, so it doesn't get too disorganized.

    Don't get discouraged because you might have a million or two strings you need to deal with - the computer doesn't care, and will run through it like crap through a goose, once you get it set up right.

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by MAtkins View Post
    In the code below, is there any way to deallocate the memory of buff1 after I've copied all but the first 5 characters to buff2?
    Yes. Place the lines in their own block. Local variables (or arrays) cease to exist when they pass out of scope. You will need to reorder things if you want buff2 to subsequently exist though.

    Code:
    int main()
    {
        char buff2[4096];
    
        {   /*  start a new block */
    
             char buff1[4096]="http://www.softlinksys.com/Programming/aspnet.php";
            strcpy(buff2, buff1 + 5);
        }   /* close the block.    buff1 ceases to exist, as far as your code is concerned */
    
         /* do something with buff2
         return 0;
    }
    Quote Originally Posted by MAtkins View Post
    Also, is there anything I can do to truncate the allocated memory to only what I need for buff2?
    That depends on what you mean by "truncate". strlen() will report strlen(buff2) is of the length you intend. However, the buff2 will still consume 4096 bytes of memory.

    If by "truncate" you mean "shorten the allocated length to no more than necessary", you can use dynamic memory allocation
    Code:
        char *buff2;
    
         /*  and later .... */
    
        buff2 = malloc(strlen(buff1) + 1);   /*  +1 allows for terminating nul character */
        strcpy(buff2, buff1);
    of course, you have to remember to free(buff2) when you no longer need it, in order to avoid a memory leak.

    Incidentally, when creating buff1, you are initializing with a string literal, so there is no need to specify a length of 4096. Instead you can do
    Code:
    	char buff1[]="http://www.softlinksys.com/Programming/aspnet.php";
    	strcpy(buff2, buff1 + 5);
    There are a few more devious tricks, but I'll stay quiet on those.
    Last edited by grumpy; 02-11-2011 at 05:16 AM.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  9. #9
    Registered User
    Join Date
    Feb 2011
    Posts
    96
    Please bear with me here.
    Realize that this code is for me to learn, it's not actual code.
    I'll have muliple string functions that I need to run a string through and I'm trying to allocate as little memory as I can.

    How much memory do I have allocated just before I return main?
    I'm thinking that now I a total of 8192 in 2 variables, buff1 and whatever ptrbuff1 is currently pointing at. Is that correct?
    Would the memory allocation be the same if I only had 1 shave function and ran the string through it 3 times?

    Code:
    char *shave1(char *strTest)
    {
    	char buff[4096];
    	strTest = strcpy(buff, strTest + 1);
    	return strTest;
    }
    char *shave2(char *strTest)
    {
    	char buff[4096];
    	strTest = strcpy(buff, strTest + 1);	
    	return strTest;
    }
    char *shave3(char *strTest)
    {
    	char buff[4096];
    	strTest = strcpy(buff, strTest + 1);	
    	return strTest;
    }
    int main()
    {
    	char buff1[4096]="http://www.softlinksys.com/Programming/aspnet.php";
    	char *ptrbuff1;	
    	ptrbuff1 = shave1(buff1);
    	ptrbuff1 = shave2(ptrbuff1);
    	ptrbuff1 = shave3(ptrbuff1);	
    	return 0;
    }

  10. #10
    Registered User
    Join Date
    Feb 2011
    Posts
    96
    grumpy: hmm, interesting.
    In the following code that you posted, is the memory for buff1 'freed'?
    Can it be reallocated as soon as execution leaves that block?

    Also, by truncate, yes I meant free up memory that is not actually being used.
    How can I learn how to dynamically allocate memory to a variable?

    Code:
    char buff2[4096];
    {   
    /*  start a new block */
    
             char buff1[4096]="http://www.softlinksys.com/Programming/aspnet.php";
            strcpy(buff2, buff1 + 5);
        }   /* close the block.    buff1 ceases to exist, as far as your code is concerned */
    
    // buff2 still exists but buff1 is freed now???

  11. #11
    Registered User
    Join Date
    Feb 2011
    Posts
    96
    OK, see if I've got it now, still shy the ability to dynamically allocate memory.
    I think just before I return main that I now have 4096 bytes allocated in one variable.
    Is that correct?

    Code:
    char *shave1(char *strTest)
    {
    	char buff[4096];
    	strTest = strcpy(buff, strTest + 1);	
    	return strTest;
    }
    int main()
    {
    	char *ptrbuff1;
    	{
    		char buff1[]="http://www.softlinksys.com/Programming/aspnet.php";	
    		ptrbuff1 = shave1(buff1);
    	}
    	ptrbuff1 = shave1(ptrbuff1);
    	ptrbuff1 = shave1(ptrbuff1);	
    	return 0;
    }

  12. #12
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by MAtkins View Post
    grumpy: hmm, interesting.
    In the following code that you posted, is the memory for buff1 'freed'?
    Can it be reallocated as soon as execution leaves that block?
    That is implementation dependent - it depends on your compiler. However, your code is not allowed to access buff1 BECAUSE the compiler is allowed to use that memory for something else, if it (or the author of the compiler) chooses to.

    The fact a compiler is allowed to reuse the memory does not mean it is obligated to reuse it.

    Quote Originally Posted by MAtkins View Post
    Also, by truncate, yes I meant free up memory that is not actually being used.
    How can I learn how to dynamically allocate memory to a variable?
    The example I gave using malloc() is an example of that. free(buff2) deallocates.

    Note that free(buff2) only makes the memory pointed at by buff2 unavailable to your code (accessing something after it is freed is asking for trouble). Never use free() on a pointer that was not returned by malloc(), or a related function, either.

    That is not quite the same as saying that memory is returned to your operating system though.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  13. #13
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by MAtkins View Post
    I think just before I return main that I now have 4096 bytes allocated in one variable.
    Is that correct?
    No.

    Your code returns a pointer to an array (buff) that is local to a function, so ceases to exist when the function returns.

    Both times you call shave1() ptrbuff1 in main() points at memory that is no longer accessible. If you access an element of that array (eg "ptrbuff1[0] = 'h';" in main()) your code gives undefined behaviour.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  14. #14
    Registered User
    Join Date
    Feb 2011
    Posts
    96
    If I run the code above and then:
    fprint("\n%s\n', ptrbuff1)
    it shows the URL with htt stripped.

    I think I understand though, just because the memory is 'freed' because it's out of scope doesn't mean it was written over, so when I try to read it I can. Is that correct?

    OK, how am I *supposed* to do this?

  15. #15
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by MAtkins View Post
    If I run the code above and then:
    fprint("\n%s\n', ptrbuff1)
    it shows the URL with htt stripped.

    I think I understand though, just because the memory is 'freed' because it's out of scope doesn't mean it was written over, so when I try to read it I can. Is that correct?

    OK, how am I *supposed* to do this?
    That it's not written over *yet*. You have no way of knowing when it may be overwritten, so, you should never even think about using memory after it's been freed.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 01-13-2008, 02:14 AM
  2. Question regarding Memory Leak
    By clegs in forum C++ Programming
    Replies: 29
    Last Post: 12-07-2007, 01:57 AM
  3. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 11:22 AM
  4. Shared Memory - shmget questions
    By hendler in forum C Programming
    Replies: 1
    Last Post: 11-29-2005, 02:15 AM
  5. What's the best memory (RAM) type?
    By Unregistered in forum A Brief History of Cprogramming.com
    Replies: 17
    Last Post: 12-15-2001, 12:37 AM