Accessing calloc'd data through a shared_ptr

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-24 16:48:57

问题


I'm trying to access the data that I previously allocated with the calloc method through a shared_ptr. For some reason I can't access it (keeps on crashing with EXC_BAD_ACCESS) on glTexImage2D (last line of my code snippets).

My util method to load the data:

shared_ptr<ImageData> IOSFileSystem::loadImageFile(string path) const
{
    // Result
    shared_ptr<ImageData> result = shared_ptr<ImageData>();

    ...

    // Check if file exists
    if([[NSFileManager defaultManager] fileExistsAtPath:fullPath isDirectory:NO])
    {
        ...

        GLubyte *spriteData = (GLubyte*) calloc(width * height * 4, sizeof(GLubyte));

        ...

        // Put result in shared ptr
        shared_ptr<GLubyte> spriteDataPtr = shared_ptr<GLubyte>(spriteData);
        result = shared_ptr<ImageData>(new ImageData(path, width, height, spriteDataPtr));
    }
    else
    {
        cout << "IOSFileSystem::loadImageFile -> File does not exist at path.\nPath: " + path;
        exit(1);
    }

    return result;
}

Header for ImageData:

class ImageData
{
public:
    ImageData(string path, int width, int height, shared_ptr<GLubyte> data);
    ~ImageData();

    string getPath() const;

    int getWidth() const;
    int getHeight() const;

    shared_ptr<GLubyte> getData() const;

private:
    string path;

    int width;
    int height;

    shared_ptr<GLubyte> data;
};

File that calls the util class:

void TextureMaterial::load()
{
    shared_ptr<IFileSystem> fileSystem = ServiceLocator::getFileSystem();
    shared_ptr<ImageData> imageData = fileSystem->loadImageFile(path);

    this->bind(imageData);
}



void TextureMaterial::bind(shared_ptr<ImageData> data)
{
    // Pointer to pixel data
    shared_ptr<GLubyte> pixelData = data->getData();

    ...

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, data->getWidth(), data->getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixelData);
}

Just for the record: if I throw out all shared_ptr's I'm able to access the data. Signature for glTexImage2D:

void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *data);

Additional question: normally you have to free(spriteData) but since I gave the data to a shared_ptr, will the data be free'd when the shared_ptr is removed?


回答1:


I think this is your problem:

..., &pixelData);

You are taking an address of a local variable (of type shared_ptr<GLubyte>), which is silently cast to void*, instead of getting the pointer from it. Replace it with:

..., pixelData.get());



回答2:


shared_ptr cannot magically guess how to release the memory. By default it tries to delete it, and since you didn't use new, that ends up in disaster.

You need to tell it how to do it:

shared_ptr<GLubyte>(spriteData, &std::free);


来源:https://stackoverflow.com/questions/11777119/accessing-callocd-data-through-a-shared-ptr

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