Thread: Memory Allocation In A String Class

  1. #1
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218

    Memory Allocation In A String Class

    I'm trying to make my own string class. I wrote a member function to append to a string, but I'm not sure if its very good.

    First off at the start of the code I make a pointer that points to the existing string. Then I make a new string, of the combined size. Then I copy the contents of the original, then the string to add to the new string.

    I got 2 questions here. First is: Will the memory stored at 'origin' be freed when it goes out of scope?

    Also instead of making a new string of the combined size, is it possible to resize the amount of space allocated to 'str_ptr' whilst retianing its original slot in memory? That way I wouldent have to copy its existing contents over. Or could that cause problems with whatevers stored next to it? Anyway heres my function:
    Code:
    void String::Add(char *add)
    {
    	char *origin = str_ptr;
    	
    	//Get New Size And Resize String
    	char *tmp = add;
    	while(*tmp)size++, tmp++;
    	str_ptr = new char[size];
    	
    	char *ptr = str_ptr;
    	while(*origin) *ptr=*origin, origin++, ptr++; //Copy original string
    	while(*add) *ptr = *add, ptr++, add++;		  //Copy string to append
    	++*ptr='\0';
    }
    str_ptr and size are class variables.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Will the memory stored at 'origin' be freed when it goes out of scope?
    No, you have to delete[] origin.

    Also instead of making a new string of the combined size, is it possible to resize the amount of space allocated to 'str_ptr' whilst retianing its original slot in memory? That way I wouldent have to copy its existing contents over. Or could that cause problems with whatevers stored next to it?
    I am still not entirely sure about this, but C++ does not provide an equivalent for realloc() along the lines of new[], so the simple answer is that it is not possible.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    Ok, thanks for explaining that. I tried using delete but now I get more errors. Basically I tried putting: delete origin;, delete []origin;, and delete[] origin; at the end of my function but in each case when I run the progam I get a dialog appear saying this:

    Debug Assertion Falied

    expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

    And some other stuff. I think it might have something to do with that the memory was originally assigned to the string object, but I'm not sure. Any Ideas on how to fix this?

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by mike_g View Post
    Ok, thanks for explaining that. I tried using delete but now I get more errors. Basically I tried putting: delete origin;, delete []origin;, and delete[] origin; at the end of my function but in each case when I run the progam I get a dialog appear saying this:

    Debug Assertion Falied

    expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

    And some other stuff. I think it might have something to do with that the memory was originally assigned to the string object, but I'm not sure. Any Ideas on how to fix this?
    Sounds like you are writing past the end of a buffer - or you're freeing the wrong stuff... Make sure you use delete[] and not delete <without square brackets>.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Well given that the code you have shows a memory overwrite, I guess there are other memory overwrites in your other code.
    Your size doesn't count the space for the \0

    > expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
    In addition to the block of memory you see, the environment also maintains a header block (usually just before your block) of information which describes the block allocated to you (it's size for example).
    What this assert is telling you is that at the point you try to delete the block, it has found that the associated header block has been corrupted.
    You need to find out which other allocation is going way beyond the normal boundaries of where it should go.

    > while(*tmp)size++, tmp++;
    This is a very poor use of the comma operator to avoid using braces.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Salem View Post
    > while(*tmp)size++, tmp++;
    This is a very poor use of the comma operator to avoid using braces.
    Not to mentioon that size = strlen(add) does the same thing, is most likely faster, and doesn't require any extra "tmp" variable [in this function at least].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    Well given that the code you have shows a memory overwrite, I guess there are other memory overwrites in your other code.
    Your size doesn't count the space for the \0
    The existing size should account for the null char, and since you only need one in the string I don't think thats a problem here. But I'll go over it just to be sure. Also, I'm not writing anything to 'origin', just reading from it. And it stops when it reaches the null char, which already exists.

    > expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
    In addition to the block of memory you see, the environment also maintains a header block (usually just before your block) of information which describes the block allocated to you (it's size for example).
    What this assert is telling you is that at the point you try to delete the block, it has found that the associated header block has been corrupted.
    You need to find out which other allocation is going way beyond the normal boundaries of where it should go.
    Could that be a result from doing this?:
    Code:
    char *origin = str_ptr;
    > while(*tmp)size++, tmp++;
    This is a very poor use of the comma operator to avoid using braces.
    would this be better?:
    Code:
    while(*tmp) {size++; tmp++;}
    Or is it just that beacuse its all on one line? Tbh, I don't really know any other uses for the comma operator yet.

  8. #8
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    Not to mentioon that size = strlen(add) does the same thing, is most likely faster, and doesn't require any extra "tmp" variable [in this function at least].
    Yeah I tried including <string.h>, but I got a warning saying its depricated, so I just made my own strlen code.

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by mike_g View Post
    Yeah I tried including <string.h>, but I got a warning saying its depricated, so I just made my own strlen code.
    try using <cstring> instead - that shoudl be OK.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    Ok, I'll do that then

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by mike_g View Post
    Code:
    while(*tmp) {size++; tmp++;}
    Or is it just that beacuse its all on one line? Tbh, I don't really know any other uses for the comma operator yet.
    It's better, but it's probably even better to write it over 4 lines or whatever it takes. Or, if you want it nice and succinct:
    Code:
    for(size = 0; add[size]; size++) ;
    Most people won't understand it, but it's nice and short, doesn't use any unnecessary variables, or such.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    Yeah, personally I like to do little things like that all on one line then maybe add a comment saying what it does, but I guess it may not be as readable for everyone else.

    for(size = 0; add[size]; size++) ;
    I hadent though about doing it in a for loop, but I dont think it would work for my code as size is already set to the size of the existing string, and then i'd have to find the string length of 'add' first.

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by mike_g View Post
    Yeah, personally I like to do little things like that all on one line then maybe add a comment saying what it does, but I guess it may not be as readable for everyone else.

    I hadent though about doing it in a for loop, but I dont think it would work for my code as size is already set to the size of the existing string, and then i'd have to find the string length of 'add' first.
    Ah, sorry, didn't look too carefully at the code. You would have to introduce a new variable then, e.g.
    Code:
    for(int i = 0; add[i]; i++, size++) ;
    I still think size += strlen(add) is better tho'.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    Yeah, I'll use strlen. Also I think I found whats causing this problem:

    expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

    Its because I was incrementing origin, so it was no longer at its start position. Thanks for the help guys.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Inheritance Hierarchy for a Package class
    By twickre in forum C++ Programming
    Replies: 7
    Last Post: 12-08-2007, 04:13 PM
  2. String Class
    By BKurosawa in forum C++ Programming
    Replies: 117
    Last Post: 08-09-2007, 01:02 AM
  3. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  4. structure vs class
    By sana in forum C++ Programming
    Replies: 13
    Last Post: 12-02-2002, 07:18 AM
  5. 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