5

I have to use a library function that allocates a bit of memory for a generated string and returns a char*, with the expectation that the caller eventually free the memory with free().

// Example declaration of the library function: char* foo(); // ... // Example usage: auto foo_str = foo(); // ... free(foo_str); 

Is it possible to construct a std::string from this pointer, passing ownership of the memory to the string object so it will be freed when the string is destructed? I know I could implement my own wrapper that would give this RAII behavior, but I'm guessing this wheel has already been invented once.

5
  • 1
    How about creating a std::unique_ptr from your raw pointer? Or is C++11 not an option? Commented Aug 18, 2015 at 14:41
  • unique_ptr does not use free(). It will use some form of operator delete. Commented Aug 18, 2015 at 14:44
  • 1
    @Peter unique_ptr can delete however you want it to delete. Commented Aug 18, 2015 at 14:45
  • @Michael Of course unique_ptr! I failed by not considering that. Of course C++11 is an option, I tagged the question with it :) Commented Aug 18, 2015 at 14:49
  • Ah, a -1 over a month after asking the question. I wish downvotes required comments. Commented Sep 23, 2015 at 20:13

3 Answers 3

8

No, you cannot use string for such a thing. string always owns its buffer, and will allocate and deallocate its own. You can't transfer ownership into a string. I don't even know if there's a proposal for such a thing.

There is a container that you can transfer ownership into though: unique_ptr:

struct free_deleter { void operator()(void* p) { free(p); } }; std::unique_ptr<char, free_deleter> foo_str = foo(); 
Sign up to request clarification or add additional context in comments.

2 Comments

I didn't even consider unique_ptr, which is the obvious solution. +1 for showing how to replace the deleter.
So, if my own C++ function is supposed to return std::string -- with the content returned by a C-function (such as asprintf), the only option is to copy that memory by constructing the new string-object, eh? What a waste... Sigh...
1

AFAIK std::string hasn't such constructor, that takes ownership of char*. Anyway its a bad idea to free memory outside of library, where it was allocated (if we speak about shared object or DLL).

3 Comments

The documentation of the library explicitly says that the pointer must be freed.
Usually in such situation library provides a function to free memory allocated in it.
@ElohimMeth, asprintf is a good -- if underappreciated -- example of a function, that does not...
1

You can construct a std::string from the char* pointer, but the std::string will allocate the char array itself. You will still need to free the char* returned by your library :

char* c = foo(); std::string foo_str( c ); free( c ); 

You can also create a function that ensure the deletion of the char* and return a std::string :

std::string char_to_string_with_free( const char* c ) { std::string str( c ); free( c ); return str; } 

2 Comments

return std::move( str );// std::move if using C++11 <-- AFAIK, adding std::move here can prevent Return Value Optimization, thereby leading to less efficient code.
@Michael Thanks, I ajusted the answer

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.