Barney Szabolcs
Barney Szabolcs

Reputation: 12514

How to convert safely from char* to string in legacy code?

I have the following problem:

char * cs = legacy_function();

I would refactor it to

string s = legacy_function();

but I'm guessing that the program "leaks" cs. Should I write the following then?

char * cs = legacy_function();
string s = cs; 
delete[] cs;

Or does std::string have an alternative constructor that doesn't copy cs?

Upvotes: 3

Views: 168

Answers (6)

R Sahu
R Sahu

Reputation: 206567

It will be better to create a layer of functions under a namespace and the use the functions from the namespace in rest of your code.

namespace lagacy_wrapper
{
   std::string legacy_function()
   {
      char * cs = ::legacy_function();
      std::string s = cs; 
      delete[] cs; // You'll need to use free(cs) if memory for cs
                   // was allocated using malloc family of functions.
      return s;
   }
}

and use:

std::string s = lagacy_wrapper::legacy_function();

Upvotes: 1

Simon Kraemer
Simon Kraemer

Reputation: 5670

#include <string>
#include <iostream>
#include <map>
#include <memory>

char* legacy_function()
{
    char* a = new char[100];
    memcpy(a, "Hello", 6);
    return a;
}

typedef std::unique_ptr<char[]> legacy_string_convert;

using namespace std;
int main()
{
    string s = legacy_string_convert(legacy_function()).get();
    cout << s << endl; 

}

Upvotes: 2

Baum mit Augen
Baum mit Augen

Reputation: 50053

Or does std::string have an alternative constructor that doesn't copy cs?

No, it does not. If legacy_function does a dynamic allocation (you should check this of course), you will have to match its new[] with a real delete[] or let a smart pointer handle it like this:

std::string modern_wrapper () {
    std::unique_ptr<char[]> ptr{legacy_function()};
    return std::string(ptr.get());
}

Upvotes: 1

Slava
Slava

Reputation: 44238

If you sure that returned pointer allocated by new[] and you call legacy_function() once yes you have to write it with explicit delete[]. You may also use std::unique_ptr:

std::unique_ptr<char[]> cs( legacy_function() );
std::string s = cs.get();

but if you have to call legacy_function() multiple times, I would put a wrapper that returns std::string

Upvotes: 1

Giorgi Moniava
Giorgi Moniava

Reputation: 28654

but I'm guessing that the program "leaks" cs. Should I write the following then?

You can't tell that if you don't know whether the legacy function is returning dynamically allocated memory or not.

Upvotes: 1

eerorika
eerorika

Reputation: 238311

but I'm guessing that the program "leaks" cs. Should I write the following then?

Don't guess. Read the documentation. Or if it's lacking, read the implementation.

If legacy_function allocates the string dynamically with new[], then yes, delete[] must be called when you no longer need it or else the memory leaks.

Or does std::string have an alternative constructor that doesn't copy cs?

No, it does not.

Upvotes: 4

Related Questions