c++ 如何复制已初始化为智能指针的数组?

z9gpfhce  于 2022-12-20  发布在  其他
关注(0)|答案(2)|浏览(158)

我使用std::unique_ptr<uint8[]> CPPPixelBuffer;将纹理的像素数据存储为数组。
此数组在构造函数中初始化,如下所示:

SIZE_T BufferSize = WorldTextureWidth * WorldTextureHeight * DYNAMIC_TEXTURE_BYTES_PER_PIXEL;
CPPPixelBuffer = std::make_unique<uint8[]>(BufferSize);

到目前为止,纹理的创建和绘制工作正常。(如下图所示)TextureData as the are supposed to be
现在我尝试使用for循环创建该数组的副本。(我使用for循环是因为我想稍后只提取纹理的一部分。但为了演示,我在本例中完全复制了该数组。)

SIZE_T PartBufferSize = WorldTextureWidth * WorldTextureHeight * DYNAMIC_TEXTURE_BYTES_PER_PIXEL;
std::shared_ptr<uint8[]> PartPixelBuffer(new uint8[PartBufferSize]());

// Get the base pointer of the pixel buffer
uint8* Ptr = CPPPixelBuffer.get();

//Get the base pointer to the new pixel buffer
uint8* PartPtr = PartPixelBuffer.get();

for (int i = 0; i < WorldTextureHeight *WorldTextureWidth * DYNAMIC_TEXTURE_BYTES_PER_PIXEL; i++) {

        *(PartPtr++) = *(Ptr++);
}

delete Ptr;
delete PartPtr;

复制后的像素混在一起,每次执行这段代码的图片都不一样。(如下图所示)Wrong Reults
我哪里做错了?

z31licg0

z31licg01#

最后两行错了三次。
1.数组是由智能指针管理的,不应该手工操作。
1.数组是通过new[]创建的。释放内存需要delete[]
1.指针不指向数组的开头,因为它们已在循环中递增
每个点单独使用都会导致未定义的行为。
你应该删除最后两行。不清楚为什么你认为你需要在复制数据后删除原始数据和副本。复制本身看起来还可以(尽管有更简单的方法来复制数组,如注解中所提到的)。

xt0899hw

xt0899hw2#

首先,你使用由smartpointers管理的数组。这意味着,你不需要调用delete来释放内存,当这些指针超出作用域时,它们将被释放。其次,当用C++编码时,使用std::vector而不是原始数组,因为它有一些优点,比如更好的安全性。第三,如果你使用smartpointers,那么不要显式地分配内存。我会使用函数来完成这个任务。在你的例子中,你可能需要使用std::make_shared<>()。这是一个代码示例,我创建了一个指向std::vector的智能指针,它存储了uint8_t,然后,我将该指针复制到另一个指针:

#include <iostream>
#include <memory>
#include <vector>

int main(int argc, char* argv[])
{

    auto ptr1 = std::make_shared<std::vector<uint8_t>>();
    auto ptr2 = ptr1;

    std::cout << ptr1 << '\n';
    std::cout << ptr2 << '\n';

    return 0;
}

这将打印smartpointers所指向的内存地址。注意,每次运行程序时,你会看到不同的内存地址,但这两个地址是相同的。如果你想在使用smartpointers时复制数组,你可以这样做:

#include <iostream>
#include <memory>
#include <vector>

int main(int argc, char* argv[])
{

    auto ptr1 = std::make_shared<std::vector<uint8_t>>();
    std::vector<uint8_t> vec = *ptr1;

    std::cout << ptr1 << '\n';
    std::cout << &vec << '\n';

    

    return 0;
}

这个技巧可以让你复制数组。当运行这个代码时,ptr1vec所指向的数组是相等的,但是内存地址不同。

相关问题