Terminated due to memory error

i’m trying to load a series of images in setup( ) with the following code:

std::vector<ofImage> imgs_;//declared in testApp.h


//in setup( ) of testApp.cpp
imgs_.resize(300);
for(int i=0;i<selectPatternImgs_.size();i++)
{
    char name[256];
    sprintf(name,"img%d.png",i);
    if (!imgs_[i].loadImage(name)) 
        std::cerr<<"Error! fail to load "<<name<<std::endl;        
}

each image is 1024*768 with RGBA 8 bit. i need to load 300 images, but when it loads about 90, the app crashes with the error “terminated due to memory error”
is there any way to solve this? i think it should be quite common for an app to deal with hundreds of images and even videos.
btw, i’m running the app on ipad3 with ios7.1, OF0.8.1

allocate on the heap. Cuz stack has limited memory Declare your array as.

vector<shared_ptr<ofImage> > imgs_

thanks for the reply. i’m not familiar with share_ptr, so i change my code to:

in testApp.h

std::vector<ofImage* >imgs_;

in setup() of testApp.mm

imgs_.resize(300);
for(int i=0;i<imgs_.size();i++)
{
    char name[256];
    sprintf(name,"img%d.png",i);
    ofImage* img = new ofImage();
    //if (!img.loadImage(name)) 
    if(!img->loadImage(name))
        std::cerr<<"Error! fail to load "<<name<<std::endl;   
    imgs_[i] = img; 
}

but there is still memory error.
what i want to realize is, the user could view different images when they slip a single finger left or right. could anybody suggest other solutions for this task?

if you are using pointers you have to use ‘->’

img->loadImage(name)

yep. it’s a typo when i posting. my original code compiles, but the problem is the memory error

what is the maximum number of images you can load?

about 90, with 1024*768 RGBA 8 bit

By default ofImage loads the pixels onto the graphics card memory. all 300 may not fit into the GPU memory simultaneously. If you must have all images in memory at once, load them into a vector of ofPixels (RAM based) and load those into displayable ofTexture when you need to see them on screen.

well, with a vector of ofPixels i can load about 170 images before memory error comes out. so it’s a big progress, but still not so satisfying

i also tried ofxImageSequence. with preloadAllFrames() on or off, still memory errors. very weird. is 300 images a big deal for ipad3?

In xCode can you check the memory usage, I think you press command+6 then click Memory Usage in the project navigator while your running your app. Do this with 170 images cause you said that did not crash.

Also can you post the code you used with ofPixels?

here are the codes:

ofApp.h

#pragma once

#include "ofMain.h"
#include "ofxiOS.h"
#include "ofxiOSExtras.h"

class ofApp : public ofxiOSApp {
	
    public:
        void setup();
        void update();
        void draw();
        void exit();
	
        void touchDown(ofTouchEventArgs & touch);
        void touchMoved(ofTouchEventArgs & touch);
        void touchUp(ofTouchEventArgs & touch);
        void touchDoubleTap(ofTouchEventArgs & touch);
        void touchCancelled(ofTouchEventArgs & touch);

        void lostFocus();
        void gotFocus();
        void gotMemoryWarning();
        void deviceOrientationChanged(int newOrientation);

    ofImage img_;
    int imgNum_;
    std::vector<ofPixels> imgs_;
    int imgIdx_;
};

ofApp.mm

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){	
    ofBackground(0);
    ofSetFrameRate(20);
    ofSetVerticalSync(true);
    ofSetOrientation(OF_ORIENTATION_90_LEFT);
    
    imgNum_ = 200;
    imgIdx_ = 0;
    imgs_.resize(imgNum_);
    for(int j=0;j<imgNum_;j++)
    {
        char name[256];
        sprintf(name,"images/image%03d.jpg",j);
        if (!img_.loadImage(name)) {
            std::cerr<<"Error! fail to load "<<name<<std::endl;
        }
        else
        {
            std::cout<<"load "<<name<<std::endl;
            imgs_[j].setFromPixels(img_.getPixels(), img_.getWidth(), img_.getHeight(), 3);
        }
    }
    
}

//--------------------------------------------------------------
void ofApp::update(){

}

//--------------------------------------------------------------
void ofApp::draw(){
	ofSetColor(255, 255, 255);
    img_.draw(0, 0);
    
    imgIdx_++;
    if (imgIdx_ >= imgNum_) {
        imgIdx_ = 0;
    }
    img_.setFromPixels(imgs_[imgIdx_]);
}

//--------------------------------------------------------------
void ofApp::exit(){

}

//--------------------------------------------------------------
void ofApp::touchDown(ofTouchEventArgs & touch){

}

//--------------------------------------------------------------
void ofApp::touchMoved(ofTouchEventArgs & touch){

}

//--------------------------------------------------------------
void ofApp::touchUp(ofTouchEventArgs & touch){

}

//--------------------------------------------------------------
void ofApp::touchDoubleTap(ofTouchEventArgs & touch){

}

//--------------------------------------------------------------
void ofApp::touchCancelled(ofTouchEventArgs & touch){
    
}

//--------------------------------------------------------------
void ofApp::lostFocus(){

}

//--------------------------------------------------------------
void ofApp::gotFocus(){

}

//--------------------------------------------------------------
void ofApp::gotMemoryWarning(){

}

//--------------------------------------------------------------
void ofApp::deviceOrientationChanged(int newOrientation){

}

for the above codes, i can load about 200 images. memory usage is 458M

each image will be about 3.14 MB. So 458 looks right. The ipad3 only has 1 GB. And each application is only allowed to use 512 MB of ram max. Looks like you maxed out

1 Like

You have power to burn on an ipad3, you could take all the loading out of the setup and have a streamer of sorts. eg. Have a thread loading a bunch of ofPixels into a fixed size queue (say 30). After you have drawn the first image, pop it out of the queue and delete the ofPixels. The thread then loads/pushes new images into the queue.

There’s a bit of overhead with the constant loading and deleting, but it’s the only way you can play 500+ big images on an ios device.

1 Like

yes. maybe this is the only way.
btw, i just find a weird thing that, i run the same app on ipad3 and iPad mini2 respectively, but the memory usage is 230M and 430M respectively. don’t know why there is so big difference.