问题
template<typename T>
static T *anydup(const T *src, size_t len) {
T *ptr = malloc(len * sizeof(T));
memcpy(ptr, src, (len * sizeof(T)));
return ptr;
}
Is this proper? Can I expect any errors from this when using an int, long, etc.? I'm very new to generic programming and am trying to learn more.
回答1:
No this is not proper ! When you have a malloc()
in C++ code, you should become very suspicious:
malloc()
allocates memory, but doesn't properly create objects. The only way to work with such memory would be to use a placement new.memcpy()
doesn't respect the copy semantic of C++ objects. This could only work with trivially copiable classes. I would cause hard to find bugs elsewhere (shallow copies, and other awful things that lead to UB).
For basic types like char, int, double, it would work. But not for more complex types.
Alternative 1: adapt your code to properly create and copy objects
template<typename T>
T *anydup (const T *src, size_t len) {
T *ptr = new T[len]; // requires that T has a default constructor
copy (src, src+len, ptr); // requires that T is copyiable
return ptr;
}
Attention: risk of memory leakage if user forget to delete the array, or UB if user doesnet use delete[]
! To avoid this you could opt for returning unique_ptr<T[]>
.
Alternative 2: Get rid of arrays and pointers and memory nightmares: use vectors !
template<typename T>
vector<T> anydup (const vector<T> src) {
vector<T> v(len); // requires that T has a default constructor
copy (src.cbegin(), src.cend(), v); // requires that T is copyable
return v;
}
You could consider creating the vector using a copy constructor as suggested by Remy Lebeau and FDinoff in the comments, either in the function or directly in the using code.
If you use copy()
directly in the using code, you'll soon discover that there are also copy_if()
, copy_backwards()
and some other nice <algorithms>
that could be used depending on circumstances.
来源:https://stackoverflow.com/questions/39690024/a-templated-strdup