1

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?

polyclick
  • 2,704
  • 4
  • 32
  • 58
  • I honestly wonder if the code really needs all those `shared_ptr`s all over . – R. Martinho Fernandes Aug 02 '12 at 12:13
  • Also, `ImageData` doesn't seem to follow the [rule of three](http://stackoverflow.com/search?q=%5Bc%2B%2B-faq%5D+rule+of+three). – R. Martinho Fernandes Aug 02 '12 at 12:18
  • @R.MartinhoFernandes well actually I'm wondering the same. I've started using shared_ptr because for the most part is leans very closely to the way I'm used to coding in Objective-C. So there are two reasons why I'm using them almost everywhere (except for primitive types like int). 1. because of the automatic reference counting and destruction of objects. 2. to solve the try catch and all kind of scope problems that might occur and autoreleasing comes in handy. Please feel free to enlighten me I'm just getting started with c++ ;) – polyclick Aug 02 '12 at 12:49
  • This would probably work better in chat. Feel free to come by the [C++ room](http://chat.stackoverflow.com/rooms/10/loungec) and mention it. I'm sure either I or someone else will be glad to help you out. – R. Martinho Fernandes Aug 02 '12 at 13:08

2 Answers2

4

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);
R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
3

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());
Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171