HEAP CORRUPTION with Dynamic Arrays

Jun 28, 2009 at 5:30pm
I'm using VC++ 2008 and when I create a pointer as follows:

unsigned int size = 3;
char *string = new char[size];


and print the size of the string using strlen I get:

cout << strlen(string) << endl;

output---> 7 (7? but size = 3...)


and print the empty string I get:

cout << string << endl;

output---> ===zzzz (the z's are actually strange looking z's)


but if I use a for loop to enter data into the string:

int character = 65;

for ( unsigned int index = 0; index < size; index++, character++ ) {
string[index] = (char)character;
}


and then print the string out:

cout << string << endl;

output---> ABCzzzz (those damn z's again)


however, in an attempt to solve the problem I tried to add a null terminator at:

string[size] = '\0';

but when I try to use:

delete [] string;

I get a HEAP CORRUPTION error.

Basically I'm trying to create my own string class for educational purposes. So I'm creating a class that accepts a pointer to a string:

String string( "hello world" );

and determining the length of the string in the constructor so that other functions (such as find, or sort) know the length for use with the corresponding for loops.

I can't seem to find other examples of this problem. I thought it was just my computer perhaps but my laptop has the exact same problem.

Thanks for any assistance.
Last edited on Jun 28, 2009 at 5:37pm
Jun 28, 2009 at 5:41pm
You are creating an array of size 3, and not initializing them to \0 or anything. Therefore, there is no null character until later (which is why you see the weird Zs, they are guard bytes). When you do string[size] = '\0', you are accessing an out of bound element since your array only goes from 0-2.
Jun 28, 2009 at 5:54pm
Nice, seems to be working perfect now. =)

Btw, does it matter when I initialize (size - 1) index to NULL?

Thanks again.
Jun 28, 2009 at 6:41pm
If you want to use C-string functions and other stuff then yes, you want to assign the final byte to be '\0' before you use them (NULL or 0 also works). Otherwise, not really. If you just want an array of characters (as opposed to a c-string) then you don't have to care about the null character at the end.
Jun 29, 2009 at 2:24am
I would also like to add that this is what strlen() looks like:
1
2
3
4
5
6
size_t strlen(const char *str){
    size_t size=0;
    while (*str++)
        size++;
    return size;
}

strlen(), as you can see, doesn't "detect" the size of the array passed to it (that's impossible). It merely counts how many characters from the pointer to the next '\0'.
Jun 30, 2009 at 9:25am
Somewhat related, but can anyone explain the difference between:

unsigned int length = 6;
char string[length] = "hello";

char *stringPtr = new char[length];
stringPtr[length - 1] = '\0'; // error occurs with or without this statement

stringPtr = string

delete [] stringPtr; // causes BLOCK_TYPE_IS_VALID error



...and...


unsigned int length = 6;
char string[length] = "hello";

char *stringPtr = new char[length];
stringPtr[length - 1] = '\0';

for ( unsigned int index = 0; string[index] != '\0'; index++ )
stringPtr[index] = string[index];

delete [] stringPtr; // does not cause an error


Thanks again =)
Last edited on Jun 30, 2009 at 11:43am
Jun 30, 2009 at 12:04pm
since stringPtr is a char* and string is also a char* (array), your first example simply assigns a pointer just the same as x = y assigns an int if x and y are ints. string is a pointer to stack memory; the assignment stringPtr = string; sets stringPtr to point to stack memory which you then attempt to free using delete []. But since stack memory is not allocated via new [], the delete [] corrupts the heap.

the second example actually copies the contents of the string since stringPtr[x] is a char and string[x] is a char.
The delete works here since stringPtr is still a pointer to heap memory; it was allocated via new [].
Jun 30, 2009 at 12:28pm
So would assigning a heap created pointer to a stack created pointer create a memory leak since I can no longer delete the pointer that pointed to the heap?
Jun 30, 2009 at 3:42pm
@romasi. Yes. In your first example, you actually allocated memory for stringPtr and then reassigned the pointer to the address of the array that was created on the stack. At that point you have a memory leak.

By the way, in the first part of your example you are creating an array with a non-const expression which is illegal C++ syntax. I don't know why the compiler you use allows you to do that. It'd be better to do it like this. There is less chance that you will define the array incorrectly since the compiler can determine how big mystring needs to be. Then you can determine the length afterwards.

1
2
char myString[] = "hello";
unsigned int length = strlen(myString);
Last edited on Jun 30, 2009 at 3:46pm
Topic archived. No new replies allowed.