Realizing memdup() compactly in C++

N

Nordlöw

Han anybody written any snippet (template i guess) that realizes memdup
() using the operator new. Suggested name: new_duplicate.

Thanks in advance,
Nordlöw
 
V

Victor Bazarov

Nordlöw said:
Han anybody written any snippet (template i guess) that realizes memdup
() using the operator new. Suggested name: new_duplicate.

What is it you're trying to accomplish with it? Are you trying to get
'memdup' to use the same *allocation function* as 'new'? Also, see FAQ
5.2, perhaps it's relevant.

V
 
N

Nordlöw

What is it you're trying to accomplish with it?  Are you trying to get
'memdup' to use the same *allocation function* as 'new'?  Also, see FAQ
5.2, perhaps it's relevant.

V

Ooops, memdup() was defined by me... Here's the definition:

static inline char *
memdup(const char *s, size_t n)
{
char * t = (char*)malloc(n);
memcpy(t, s, n);
return t;
}

Sorry,
Nordlöw
 
V

Victor Bazarov

Nordlöw said:
Ooops, memdup() was defined by me... Here's the definition:

static inline char *
memdup(const char *s, size_t n)
{
char * t = (char*)malloc(n);
memcpy(t, s, n);
return t;
}

Uh... So, what's stopping you from replacing a call to malloc with a
'new[]' expression? Or do you want it to work with any type?

It's not a good idea to implement a memory "allocation" *function* using
'new[]', however, because, since it looks too much like 'malloc',
somebody will try to use 'free' on the pointer it returns, which has
undefined consequences, I believe. Currently I need to use 'free', and
it is consistent.

V
 
T

Thomas J. Gritzan

Ooops, memdup() was defined by me... Here's the definition:

static inline char *
memdup(const char *s, size_t n)
{
char * t = (char*)malloc(n);
memcpy(t, s, n);
return t;
}

You should really start using C++ facilities like std::vector<TYPE> or
std::string.

However, if you want to copy non-POD objects that can't be copyied by
memcpy, use std::copy instead.
 
M

Marcel Müller

Nordlöw said:
Han anybody written any snippet (template i guess) that realizes memdup
() using the operator new. Suggested name: new_duplicate.

// Array
vector<MyObject>* array;
....
vector<MyObject>* copy = new vector<MyObject>(*array);


// Single Object
class MyObject;

MyObject* obj;
....
MyObject* copy = new MyObject(*obj);

This method does not work with polymorphic types. If you want to support
polymorphic types, you need an abstract clone() method, that is
redefined by any non-abstract class that inherits from MyObject.


// Array w/o wrapper class
MyObject* array;
size_t count;

MyObject* copy = new MyObject[count];
const MyObject* src = array;
const MyObject* src_end = array + count;
MyObject* dst = copy;
while (src != src_end)
*dst** = *src++;

This solution can be encapsulated in a function, of course. But is has
some major disadvantages and therefore I do not recommend to use
something like that.
- First of all the array root and the array size are not encapsulated by
an object and can get out of sync resulting in undefined behavior.
- Secondly the function initialize the destination objects by the
default constructor and assign the content later. This is not very
efficient in general. Of course, you could work around this by using the
placement new operator. This is the way most std::vector implementations
work.
However, there is still the first issue, so why not use std::vector and
forget about new_dup?


Marcel
 
J

James Kanze

Uh... So, what's stopping you from replacing a call to malloc
with a 'new[]' expression? Or do you want it to work with any
type?

Isn't what he's really looking for something more along the
lines of:

template< typename T >
T*
new_duplicate( T const& original )
{
return new T( original ) ;
}

Although I really don't see the need for a special function to
do this (except maybe obfuscation).
 
J

Juha Nieminen

James said:
Isn't what he's really looking for something more along the
lines of:

template< typename T >
T*
new_duplicate( T const& original )
{
return new T( original ) ;
}

Although I really don't see the need for a special function to
do this (except maybe obfuscation).

Yeah. Why wouldn't this do:

std::vector<YourType> original;
std::vector<YourType> duplicate = original;

It sounds *exactly* what that "new_duplicate" is supposed to do. Only
safer.
 
J

James Kanze

James Kanze wrote:
Your example won't work when T is an array.

Have you actually tried it:

std::vector< int >* p = new std::vector< int >( oldVector ) ;

works for me. Ditto for tr1::array. (Of course, as Juha
pointed out, just assigning the arrays is probably more
appropriate. There's almost never any reason to allocate an
array dynamically.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,015
Latest member
AmbrosePal

Latest Threads

Top