3

I've exhausted myself googling this, but I haven't been able to find a clear answer or help myself understand what is going wrong. As part of a homework assignment, I'm trying to dynamically allocate memory for a character array (ie. a CString) and assign a char pointer variable to point at it, then delete the allocated memory before I end the program. I'm just wrapping my head around pointers so I suspect that some of my understanding of what's happening behind the scenes is not correct, and I'm ending up with Visual Studio 2010 giving me heap corruption breakpoints.

Here's a simplified version of what I'm trying to do (my comments indicate what I think I'm doing):

char *chPtr = new char[10]; // Create a char pointer type variable, and point it at the memory allocated for a char array of length 10
chPtr = "September";        // Assign 9 characters (+1 null terminator character) to the char array
cout << chPtr;              // Prints "September", then finds the null terminator and stops printing
delete [] chPtr;            // THIS is what causes my heap corruption -> But I don't know why. Shouldn't this delete the array of memory that chPtr is pointing at?
  • I've tried using delete chPtr as well, with the same heap corruption result.
  • I've tried manually assigning a null terminator to the end of the array chPtr[9] = '\0'; , but this also results in heap corruption. Why? I can access individual characters from within the array when I do things like cout << chPtr[7]; etc without any problems...

What's really confusing is that this works without error:

char *chPtr = new char[10]; // As above, create a char pointer type and point it at the memory allocated for a char array of length 10
delete chPtr;               // This doesn't give any error!

It seems that initializing the array by assigning a value is breaking things for me somehow.

Can anybody help me out?

b1skit
  • 327
  • 4
  • 16

5 Answers5

1

chPtr = "September"; changes where chPtr is pointing. Instead of pointing to wherever your array of 10 chars was allocated, it is now pointing to the static character array "September". You are then trying to delete that, which fails.

As a test, you can try this:

char* p = nullptr;
std::cout << static_cast<void*>(p) << "\n";

p = new char[10];
std::cout << static_cast<void*>(p) << "\n";

p = "September";
std::cout << static_cast<void*>(p) << "\n";

A possible output would be:

00000000
0068C988
00D18B34

You can see that the address where p is pointing changes at every assignment. The block allocated on the free store (0068C988) is lost on the third assignment.

If you want to assign characters, do something like

std::strcpy(chPtr, "September");

This comes with all the caveats of memory management, arrays and pointers. What you really want to do is:

std::string s = "September";
std::cout << s;
isanae
  • 3,253
  • 1
  • 22
  • 47
0

You are trying to delete a block of memory where your "September" is located and it's definitely is not allocated in heap, if you need to initialize pre-allocated buffer use strcpy(..) functions.

evilruff
  • 3,947
  • 1
  • 15
  • 27
  • There is no *"heap"*, as far as C++ is concerned (at least not the way you are using it). You are probably referring to [*"free store"*](http://stackoverflow.com/q/6161235/1889329) instead. – IInspectable May 31 '15 at 21:44
0

this is the source of your problem:

char *chPtr = new char[10]; // Create a char pointer type variable, and point it at the memory allocated for a char array of length 10
chPtr = "September";  

first you allocate a heap memory on chPtr , then allocate a non-heap memory (Data segment memory, if to be precise) by assigning the non-heap char array with the value of "september" on it.

you try to delete non-heap memory , then you get the error you get.

use strcpy(chPtr,"September") or even better : lose the C and use std::string.

David Haim
  • 25,446
  • 3
  • 44
  • 78
  • Ahhh, this makes sense. To help me understand this fully, how would I go about assigning a literal (ie. "September") into the memory allocated by `new`, without the use of strcpy() ? – b1skit May 31 '15 at 20:57
  • 1
    C++ knows nothing of heap, non-heap and data segments. `"September"` is not a "temporary string". This is not assigning a string, but a pointer to an array of characters. – isanae May 31 '15 at 21:00
  • you can't really do it on C or C-like-code since `new char[]` allocate a series of bytes without really asigning them any value. an array of bytes does not have a constructor to work upon, it's just a block of memory. you have to use some memory-copying function like `strcpy` or `memcpy`. you can however create `std::string ` on the heap and assign a literal to it by `new std::string("September")`. this said, `std::string` already keeps its inner buffer on the heap, so there is no actual need to create heap-based std::string – David Haim May 31 '15 at 21:00
  • @isanae I accept your comment, I edited my answer a bit. – David Haim May 31 '15 at 21:02
  • I see. So, to assign values to the memory allocated by `new` without using `strcpy`, I'd need (for example) to create a function that looped through my array index by index (ie memory address by memory address) and manually assigned each char? – b1skit May 31 '15 at 21:06
0

The assignment chPtr = "September"; doesn't do what you think it does. It assigns the address of the static character array "September" to the variable chPtr. When you try to invoke operator delete[] on it, things go wrong: You're trying to delete a statically allocated character array.

If you wish to copy characters, you will have to use a string copy function like std::strcpy.

Of course, the correct way to use C-style strings in C++ is to not use C-style strings. Use one of the standard C++ std::basic_string templates.

IInspectable
  • 46,945
  • 8
  • 85
  • 181
0

chPtr = "September" doesn't assign anything to the memory pointed to by chPtr instead it assigns chPtr to point to some other memory that does hold "September". You can't delete this memory.

rds504
  • 146
  • 6