¿Cómo no puedo eliminar pwstr?

Please, could someone explain me why this code give me the error in runtime "expression _block_type_is_valid(phead- nblockuse)"?

#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
#include <shlobj.h>
#include <iostream>

using namespace std;

int main() {
    PWSTR path;
    HRESULT hr = SHGetKnownFolderPath(FOLDERID_Desktop, 0, NULL, &path);
    delete[] path;
    return 0;
}

preguntado el 02 de diciembre de 13 a las 16:12

...because you did not new it. -

To be precise, because you did not new[] it. C++ is not forgiving. You must match each allocation with the right deallocation function. -

Tienes que usar CoTaskMemFree en el puntero regresó de SHGetKnownFolderPath, porque usa CoTaskMemAlloc internamente. new y delete in C++ use a completely different memory system -

2 Respuestas

Because the memory is not allocated by new. De hecho, si tu lee la documentación you will see that:

The calling process is responsible for freeing this resource once it is no longer needed by calling CoTaskMemFree.

Respondido el 02 de diciembre de 13 a las 16:12

@user3058108 Windows have many different allocation/free systems, depending on what the memory will be used for. You should normalmente utilizan el new/delete in your program, but for some Windows API functions you need to use other allocation functions. - Algún tipo programador

@user Windows doesn't know which allocator you like to use. And Windows is runtime agnostics. You might not be used C++. Many other languages are able to call that API function. So Windows uses its own allocator (the COM heap), exports that allocator, and tells you to use it to free the memory. You aren't stupid, you just have not learnt this stuff yet. But you really should get into the habit of reading the docs. - David Heffernan

I think (but haven't checked) that you can use smart pointers for this: std::unique_ptr<WCHAR> path_ptr(path, &CoTaskMemAlloc);. This tells C++ that the memory must ultimately be deleted by CoTaskMemAlloc, but it relieves you from figuring out exactly cuando that needs to happen. - MSalters

@MSalters It would be CoTaskMemFree. But it's generally best just to copy it to a string object, and free the raw memory immediately. - David Heffernan

@IInspectable: Why would that be a problem? LPVOID is just a verbose way to write void*, and any pointer converts a void*. It's the conversion a partir de octubre XNUMX void* which requires a cast. - MSalters

There's a more general answer to this (implied by @Joachim's answer):

En Windows, memory is allocated by a soluciones function, and must be freed by its corresponding deallocator.

Furthermore, even within a specific language (say, C++), memory can be allocated from multiple heaps, and must be freed within that heap. (C/C++ DLLs, in particular, get their own heap at load time, and memory allocated by that DLL must be freed by that DLL. Do it wrong, and you get memory corruption and crashes.)

COM has its own allocator/deallocator (CoTaskMemAlloc/CoTaskMemFree) that is probably the closest thing you'll get to a system-wide allocation function; but even that is mostly used by the shell APIs, and many other Win32 APIs that allocate memory don't use that.

Respondido el 02 de diciembre de 13 a las 18:12

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.