smart pointer array deletor

喜你入骨 提交于 2019-12-12 19:15:35

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!