views:

353

answers:

8

I have pointer str:

char* str = new char[10];

I use the memory block str points to to store data.

How can I allocate more bytes for the buffer pointed to by str and not lose old data stored in the buffer?

+3  A: 

You cannot using the new construction. For that you need to use the good old malloc, realloc, and free (do not mix malloc/realloc/free and new/delete).

Tony Olsson
Actually you can - new[] a new buffer, copy data, delete[] the old one. Not a one-liner, but that's kind of what realloc() does.
sharptooth
@sharptooth: not exactly. The OS (at least linux) will try to actually grow the memory in place. If there is enough contiguous space after the allocated space, the operation will not incur the cost of copying.
David Rodríguez - dribeas
@David Rodríguez - dribeas: Yes - in terms of implementation - but the OP doesn't insist on "no copying", he only asks for data preserving.
sharptooth
+15  A: 

Use std::string instead. It will do what you need without you worrying about allocation, copy etc. You can still access the raw memory via the c_str() function.

Even std::vector<char> will work well for you.

Klaim
+1 for c++ way to do it.
Mark B
+6  A: 

new[] another buffer, copy the data there (use memcpy() for that), then delete[] the old one, assign the new buffer address to the pointer originally holding the old buffer address.

sharptooth
A: 

The realloc function is what you are searching for. You had to use malloc/free instead of new/delete to use it

Patrice Bernassola
realloc() does *not* work with memory allocated with "new".
Ant
You are right Ant, but he can maybe change the allocation method...
Patrice Bernassola
Not sure, why this is down-voted, the OP either needs to use std::string/std::vector<char> or need to allocate the memory using malloc/realloc/free instead of new/delete.
Narendra N
A: 

You have to allocate a different, bigger string array, and copy over the data from str to that new string array.

Martin
A: 

You can use realloc: http://www.cplusplus.com/reference/clibrary/cstdlib/realloc/ I would add that this approach is not the favored c++ approach (depending on your needs you could use std::vector<char> for instance).

Francesco
Be aware that `realloc` may silently move the allocation thus invalidating other pointers.
Brian Rasmussen
You're right to point it out. Actually, in a C++ program I advice against using it (there used to be a reference to C which has been edited out by now, when I answered at first).
Francesco
A: 

Allocation is a bit like finding a parking place. You're asking here if it's possible to add a trailer on your car that has been parked for a fews days.

The answer is, in C there exists something called realloc that allows you to do following thing. If I have already enough place to add my trailer, do so. If not park in another place big enough for your trailer and your car, which is equivalent to copying your data.

In other words you'll get strong and random performance hits.

So what would you do in the real world? If you knew you might need to add some trailers to your car you'd probably park in a bigger place than required. And when exceeding the size required for the place, you'd move your car and your trailers to a place with a nice margin for future trailers.

That's precisely what the STL's string and vector is doing for you. You can even give them a hint of the size of your futures trailer by calling "reserve". Using std::string is probably the best answer to your problem.

poulejapon
+1  A: 

If you are really using C++, the most correct solution would be to use std::vector. I assume that you are not using that information as a standard string, in that case you should use std::string (which is an specialization of std::vector, so no big deal). You are creating at least 10 chars. This gives me the hint that you are probably quite sure that you'll need 10 chars, but maybe you'll nedd more. Maybe you are worried about the performance problems involved in allocating and deallocating memory. In that case, you can create your string and then reserve the estimated capacity that you expect you'll need, so there won't be any reallocation at least until you get to that limit.

int main()
{
    std::string s;
    s.reserve( 10 );
    // do whatever with s
}

As others have already pointed out, the use of std::string or std::Vector will get you the benefit of forgetting about copy, resizing or deleting the reserved memory.

Baltasarq