Trả về một con trỏ void duy nhất từ ​​một hàm


11

Để có được một void *chức năng trong CI sẽ làm một cái gì đó như thế này (ví dụ rất cơ bản):

void *get_ptr(size_t size)
{
    void *ptr = malloc(size);
    return ptr;
}

Làm thế nào để tôi đạt được kết quả tương tự khi sử dụng std::unique_ptr<>?



1
Vui lòng giải thích vấn đề bạn gặp phải khi thực hiện nó.
molbdnilo

1
Xem câu trả lời này để biết chung void unique_ptr: stackoverflow.com/a/39288979/2527795
vll

Xin lưu ý rằng hầu như không bao giờ có lý do để sử dụng malloctrong C ++ như thế này. Bạn đang trả lại một con trỏ vào bộ nhớ thô, rằng bạn cần đặt các đối tượng mới vào trước khi bạn được phép sử dụng nó. Nếu bạn không có lý do chính đáng để tạo các đối tượng sau đó so với khi bạn phân bổ bộ nhớ, thì bạn nên sử dụng newhoặc std::make_uniquesẽ phân bổ bộ nhớ, cũng như tạo các đối tượng phù hợp. Trong cả hai trường hợp std::vectorvới reservelà thăm dò. tốt hơn nữa Ngay cả khi bạn không sử dụng chúng, đây không phải operator newlà cách phân bổ bộ nhớ thành ngữ malloc.
quả óc chó

Câu trả lời:


18

Bạn cần chỉ định deleter tùy chỉnh để sử dụng voidlàm unique_ptrđối số kiểu như thế:

#include <memory>
#include <cstdlib>

struct deleter {
    void operator()(void *data) const noexcept {
        std::free(data);
    }
};

std::unique_ptr<void, deleter> get_ptr(std::size_t size) {
    return std::unique_ptr<void, deleter>(std::malloc(size));
}

#include <cstdio>
int main() {
    const auto p = get_ptr(1024);
    std::printf("%p\n", p.get());
}

2

Đơn giản hóa câu trả lời của @ RealFresh bằng cách sử dụng std::freetrực tiếp như deleter thay vì xây dựng functor:

auto get_ptr(std::size_t size) {
    return std::unique_ptr<void, decltype(&std::free)>(std::malloc(size), std::free);
}

Xem bình luận của tôi về câu hỏi, mặc dù.


1

Thay vào đó, hãy xem xét trả về một con trỏ tới mảng char:

#include <memory>

std::unique_ptr<char[]> get_ptr(std::size_t size)
{
    return std::make_unique<char[]>(size);
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.