Q:

C++ memory - Do primitive-typed variables created with 'new' need to be deleted?

I'm kind of new when it comes to memory management in C++. I read that if you create a class with the new keyword you must delete the object to free its memory. I also read that primitive types, such as int, char and bool, are created on the stack, which means they get deleted when they go out of scopes.
But what about primitive types created with the new keyword? Do I need to explicitly call delete? Are these created on the heap like classes? Or since they are primitive do they still get created on the stack?
I am asking because I am allocating a LPTSTR using the new keyword, but I am worried that if I do not call delete that the memory will never be freed. Here is my code with the bare question in the comments:
#include <Windows.h>
#include <tchar.h>
#include <string>

#ifdef _UNICODE
    typedef std::wstring Str;
#else // ANSI
    typedef std::string Str;
#endif

Str GetWndStr(HWND hwnd) {
    const int length = GetWindowTextLength(hwnd);

    if (length != 0) {
        LPTSTR buffer = new TCHAR[length + 1]; // Allocation of string
        GetWindowText(hwnd, buffer, length + 1);
        Str text(buffer);

        delete buffer; // <--- Is this line necessary?
        return text;
    } else {
        return _T("");
    }
}

Do I need to call delete? Awhile back, I tried using GlobalAlloc() and GlobalFree(), but during runtime I got an error saying something about illegally modifying the stack, I do not have an exact error message as this was awhile ago. Also, in addition to your answer, if you would like to give me resources you found helpful to learn more about C++ memory management, that would be nice.

A:

For every new there must be a delete and for every new[] there must be a delete[]. Notice that the memory allocated with new[] must be deleted with delete[], which is not the case in the posted code.
A smart pointer can be used, boost::scoped_array for example, which will perform the delete[] in its destructor (or reset() function). This is particularly useful if exceptions can be thrown after the call to new[]:
boost::scoped_array<TCHAR> buffer(new TCHAR[length + 1]);
GetWindowText(hwnd, buffer.get(), length + 1);
Str text(buffer.get()); // buffer will be deleted at end of scope.

A:

Your array is allocated with new[] and therefore must be deleted with delete[] (not delete).
Your explicit dynamic allocation is also unnecessary:
Str text(length+1, 0);
GetWindowText(hwnd, &text[0], length + 1);
text.resize(length); // remove NUL terminator
return text;

In C++03 there's some justification needed, whether string and wstring actually allocate contiguous memory, suitable for passing as a buffer. It's not guaranteed by the C++03 standard, but it is in fact true in MSVC++. If you don't want to rely on that fact, then it is guaranteed for vector, so you can use that for the buffer:
std::vector<TCHAR> buffer(length+1);
GetWindowText(hwnd, &buffer[0], length + 1);
return Str(buffer.begin(), buffer.end() - 1);

It is pretty rare to directly use new[] in C++. In both cases, my vector or string buffer is an automatic variable, so I don't have to do anything special to make sure that it is destroyed correctly when its scope ends.

