views:

179

answers:

5

Okay the previous question was answered clearly, but i found out another problem.

What if i do:

char *test(int ran){ 
    char *ret = new char[ran]; 
    // process... 
    return ret; 
} 

And then run it:

for(int i = 0; i < 100000000; i++){ 
   string str = test(rand()%10000000+10000000); 
   // process... 

   // no need to delete str anymore? string destructor does it for me here?
} 

So after converting the char* to string, i dont have to worry about the deleting anymore?

Edit: As answered, i have to delete[] each new[] call, but on my case its not possible since the pointer got lost, so the question is: how do i convert char to string properly?

+1  A: 

Yes, yes you do.

If you are using linux/os x, look into something like valgrind which can help you with memory issues

You can change your test function so that it returns a string instead of char *, this way you can delete [] ret in the test function.

OR you could just use a string in test as well and not have to worry about new/delete.

Dan McGrath
So i have to use: delete[] str; ?
Newbie
No, str is it's own object. In this case, you have lost the pointer to the new char[] you allocated and hence will have a memory leak since you cannot delete it.
Dan McGrath
+8  A: 

Here you are not converting the char* to a [std::]string, but copying the char* to a [std::]string.

As a rule of thumb, for every new there should be a delete.

In this case, you'll need to store a copy of the pointer and delete it when you're done:

char* temp = test(rand()%10000000+10000000);
string str = temp;
delete[] temp;
Johnsyweb
So how do i properly convert char to string?
Newbie
I guess when you were told to convert `char*` to `std::string`, what was meant that you should **use** `std::string` rather than `char*`, not to *convert* programatically.
Johnsyweb
Could there be any simplier way to do this ? like some kind of function or something, so it would take just one line of code?
Newbie
The simplest way to do this is to avoid using `char*` when you are storing a `string`. You *could* employ Smart Pointers, but that's a whole new can of worms that I am not prepared to open right now.
Johnsyweb
Yes, you can do something like `return string( ran, 'a' )`. Take a look at string constructors http://www.cplusplus.com/reference/string/string/string/
wheaties
+2  A: 

You seem to be under the impresison that passing a char* into std::string transfers ownership of the allocated memory. In fact it just makes a copy.

The easiest way to solve this is to just use a std::string throughout the entire function and return it directly.

std::string test(int ran){ 
    std::string ret;
    ret.resize(ran - 1);  // If accessing by individual character, or not if using the entire string at once.
    // process... (omit adding the null terminator)
    return ret; 
} 
Mark B
+1 for skipping the intermediate step of creating a char *. That said, your example code is missing a name...
R Samuel Klatchko
+1  A: 

You must call delete for every new otherwise you will leak memory. In the case you have shown you are throwing away the pointer, if you must leave the function as returning a char* then you will need to use two lines to create the std::string so you can retain a copy of the char* to delete.

A better solution would be to rewrite your test() function to return a std::string directly.

Donnie
+1  A: 

You need to do something like this:

for(int i = 0; i < 100000000; i++){ 
   int length = rand()%10000000+10000000;
   char* tmp = test(length); 
   string str(tmp);
   delete[length] tmp;
}

This deletes the allocated char-array properly.

By the way, you should always zero-terminate a string if you create it this way (i.e. inside the function test), otherwise some functions can easily get "confused" and treat data behind your string as part of it, which in the best case crashes your application, and in the worst case creating a silent buffer overflow leading to undefined behaviour at a later point, which is the ultimate debugging nightmare... ;)

Mephane