问题
Up to now i've allocated a buffer for some data processing and deleted it afterwards. Since the code got bigger and caught exceptions at some points can occur, i thought about making it safer with a std::unique_ptr and came up with those solutions:
unique_ptr<char, void (*)(void *)> p1( (char*)operator new(bufSize), operator delete);
unique_ptr<char[], void (*)(void *) > p2( (char*)operator new(bufSize), operator delete);
memcpy(&((p1.get())[0]), "xyz", 3);
memcpy(&(p2[0]), "xyz", 3);
char x1 = p1.get()[0];
char x2 = p2[0];
to me the first solutions (p1) seems to be the correct one, but it's tedious to have to write (p1.get())[...]
the second solution would be the convenient one, but here is my question:
unique_ptr seems to be templated in a special way supporting operator[], which makes me wonder, if i use unique_ptr with a custom new and delete operation, is there anything that could go wrong with the operator[] or any other functions or is the second solution (p2) fine?
回答1:
std::unique_ptr is specialised for arrays. You can just write the following:
std::unique_ptr<char[]> str(new char[4]);
char foo[] = "str";
std::copy(foo, foo + sizeof(foo), &str[0]);
If that didn’t exist you could do something similar yourself, or you could write a using
alias and a make_array
function which does the setting up for you and returns the correct type, then using it would be as simple as
auto str = make_array<char>(4);
… or something like that.
回答2:
Do not use raw buffers unless you absolutely need to (and there is rarely need to use raw buffers). You are probably best off using normal new char[n]
together with std::unique_ptr<char[]>
:
std::unique_ptr<char[]> array(new char[n]);
If you absolutely need to allocate raw memory you can use std::unique_ptr<char[], void (*)(void*)>
but the deleter function needs to match the allocation function, i.e., you need to use operator delete[]
if you allocated the memory using operator new[]
.
回答3:
std::unique_ptr
supports managing of dynamic arrays. You do not need to write your own deleter:
Example:
int main()
{
int letter{97};
int size{26};
unique_ptr<char[]> arr(new char[size]());
for (int i{}; i != size; ++i)
arr[i] = static_cast<char>(letter++); // supports subscript
for (int i{}; i != size; ++i)
cout << arr[i];
}
While std::shared_ptr
does not directly support managing of dynamic arrays, and you need to write your own deleter:
Example:
int main()
{
int letter{97};
int size{26};
shared_ptr<char> arr(new char[size](), [](char *p) { delete [] p; }); // own deleter
for (int i{}; i != size; ++i)
*(arr.get() + i) = static_cast<char>(letter++);
for (int i{}; i != size; ++i)
cout << *(arr.get() + i);
}
Since std::shared_ptr
doesn't have subscript operator and doesn't support pointer arithmetic, we can use get()
to obtain a built in pointer.
来源:https://stackoverflow.com/questions/14004576/smart-pointer-array-deletor