views:

69

answers:

1

Let's say we have an array of PRINTER_INFO_2 like this:

PRINTER_INFO_2* printers = (PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2) * 64); // room for 64 items

Then we call EnumPrinters() to get a list of locally installed printers:

EnumPrinters(
    PRINTER_ENUM_LOCAL,
    NULL,
    2,
    (LPBYTE)printers,
    ...);

Here's the structure info for PRINTER_INFO_2. Now, the string members are of type LPTSTR, so they are not stored inside of the struct itself.

What I am wondering about now, is if I can simply call free(printers) when I'm done with it, or will that result in a memory leak (all those strings not being freed)?

Will I have to call free() on every string member, like below?

free(printers[i].pServerName);
free(printers[i].pPrinterName);
free(printers[i].pShareName);
...
free(printers);

Seems awfully complicated to me this way. Especially if the struct has many, many members that needs to be freed.
Is there a better way to do this?

Thanks for helping me out with this!

+1  A: 

IIUC, you need to overallocate the buffer beyond the size of the structure, to accommodate for any output strings as well. EnumPrinters will tell you if the memory block was too small. As you can't know upfront how much memory you will need, you typically call it twice: once to learn the amount of memory needed, and the second time with an appropriately-sized buffer. You then deallocate the buffer with the same API that you used for allocation (e.g. malloc/free).

Martin v. Löwis
Aah. That makes sense! That's what I am actually doing (not part of my example here. I should have done that). Thank you so much for explaining that to me!
Kate