C++中如何用std::shared_ptr托管GetExplicitEntriesFromAcl分配的内存?
Absolutely! You can absolutely use std::shared_ptr to manage the memory allocated by GetExplicitEntriesFromAcl—the key is leveraging custom deleters in shared_ptr, which let us replace the default delete operator with LocalFree (the correct way to free memory from this Windows API).
Here's how to implement it properly:
First, you'll need to use a temporary raw pointer to receive the allocated memory from GetExplicitEntriesFromAcl, then transfer ownership of that pointer to a shared_ptr with a custom deleter that calls LocalFree:
#include <memory> #include <windows.h> // ... ULONG EntryCount = 0; EXPLICIT_ACCESS* pRawEntries = nullptr; DWORD status = GetExplicitEntriesFromAcl(pACL, &EntryCount, &pRawEntries); if (SUCCEEDED(status)) { // Create a shared_ptr that takes ownership of pRawEntries, using LocalFree as the deleter std::shared_ptr<EXPLICIT_ACCESS> pEntries(pRawEntries, [](EXPLICIT_ACCESS* ptr) { LocalFree(ptr); // This will be called automatically when the shared_ptr goes out of scope }); // Now use pEntries just like you would the raw pointer for (ULONG i = 0; i < EntryCount; ++i) { // Access entries via pEntries.get()[i] // Example: Check the access permissions of each entry // auto& entry = pEntries.get()[i]; // ... } // No need to call LocalFree(pEntries) here—shared_ptr handles cleanup automatically } else { // Handle error case; pRawEntries is nullptr here, so no cleanup needed }
Key Details to Note:
- Custom Deleter: The lambda passed to
shared_ptroverrides the default memory release logic, ensuring we useLocalFree(required for Windows API-allocated memory) instead of standard C++delete. - Exception Safety: Even if an exception is thrown while using
pEntries, theshared_ptr's destructor will still execute, guaranteeingLocalFreeis called and no memory leaks occur. This eliminates the risk of forgetting manual cleanup in complex code paths. - Raw Pointer Requirement: You can't pass a
shared_ptr*directly toGetExplicitEntriesFromAcl(the API expects anEXPLICIT_ACCESS**). Using a temporary raw pointer is the correct way to receive the allocated memory before transferring ownership to the smart pointer.
Optional: Simplify with a Type Alias
If you use this pattern frequently, create a type alias to make your code more concise:
using ExplicitAccessPtr = std::shared_ptr<EXPLICIT_ACCESS>; // Initialize like this after a successful API call: ExplicitAccessPtr pEntries(pRawEntries, LocalFree);
This works because LocalFree accepts a pointer type that can be implicitly converted from EXPLICIT_ACCESS*.
内容的提问来源于stack exchange,提问作者Siegfried

