simple program crashes brutally

Hi,

I’m working on a simple program that creates polygons out of the audiobuffer data of percussive attacks. I have no idea why, but it keeps crashing.

When it crashes, the computer is completely frozen, i can’t even force quit xcode or my app.
Perhaps there is something obvious that I am missing? I have stripped out all the elements and then put them back one a time. It worked great for a while and then started crashing again.

I get no compiler warnings and nothing from GDB(since it freezes before I can check it)
I am running OF version 0.0062, XCode 3.2.5, OS X 10.6.6 on a 2011 MacBook Pro.

If anyone has moment to browse over my testApp.cpp any comments or suggestions would be greatly appreciated!

Thank you,
Jason

#include “testApp.h”
#include “stdio.h”

const float DEG2RAD = 3.14159/180;

//--------------------------------------------------------------
void testApp::setup(){

ofBackground(0,0,0);

// 0 output channels,
// 2 input channels
// 22050 samples per second
// 256 samples per buffer
// 4 num buffers (latency)

ofSoundStreamSetup(0,2,this, 44100, 256, 4);
left = new float[256];
sumOfSquares = 0;
peakAmp = 0;
peakAmpMax = 0;

//blob variables
r = 40;
a = ofGetWidth() / 2;
b = ofGetHeight() / 2;
scale = 50;
numBlobs = 0;
freeze = false;
}

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

//this prevents more than one blob per percussive attack(well sort of…)
if (peakAmp < 0.0001) freeze = true;

if (peakAmp > 0.001 && freeze) { //make sure we are above the threshold and that we are open to freezing new blobs
if (peakAmp > peakAmpMax) peakAmpMax = peakAmp; //follow the amplitude as it rises
if (peakAmp < peakAmpMax) { //Right after the amplitude hits the maximum, create a new blob
blob newBlob;
for (int i = 0; i < 256; i++) {
float radians = (i / 256.0f * 360.0f) * DEG2RAD;
newBlob.vertices[i][0] = cos(radians) * (r + left[i] * scale) + a;
newBlob.vertices[i][1] = sin(radians) * (r + left[i] * scale) + b;
}
newBlob.red = ofRandom(0, 255);
newBlob.green = ofRandom(0, 255);
newBlob.blue = ofRandom(0, 255);
beatBlobs.push_back(newBlob);
numBlobs++;
freeze = false;
}
}

// if there are more than 10 blobs, erase the first one.
if (numBlobs > 10) {
beatBlobs.pop_front();
numBlobs–;
}
}

void testApp::draw(){
int x, y;

//draw previous blobs
for (list::iterator bb = beatBlobs.begin(); bb != beatBlobs.end(); ++bb) {
ofSetColor(bb->red, bb->green, bb->blue);
ofSetPolyMode(OF_POLY_WINDING_NONZERO);
ofBeginShape();
for (int i = 0; i < 256; i++){
ofVertex(bb->vertices[i][0], bb->vertices[i][1]);
}
ofEndShape();
}

//draw current blob
ofSetColor(0x00FFFF);
ofSetPolyMode(OF_POLY_WINDING_NONZERO);
ofBeginShape();
for (int i = 0; i < 256; i++){
float radians = (i / 256.0f * 360.0f) * DEG2RAD;
x = cos(radians) * (r + left[i] * scale) + a;
y = sin(radians) * (r + left[i] * scale) + b;
ofVertex(x, y);
}
ofEndShape();

//output data

char reportString[255];
sprintf(reportString, “peakAmp = %f\nframerate: %f\nnum blobs: %i”, peakAmp, ofGetFrameRate(), numBlobs);
ofDrawBitmapString(reportString,80,380);
}

static float adder = 0;
//--------------------------------------------------------------
void testApp::audioReceived (float * input, int bufferSize, int nChannels){
// samples are “interleaved”
sumOfSquares = 0;

for (int i = 0; i < bufferSize; i++){
left[i] = input[i\*2];
sumOfSquares += left[i] * left[i];
}
float rms = sqrt(sumOfSquares) / bufferSize;
peakAmp = 1.414 * rms;
}

Can you post your blob class? When you’re calling list.push_back() on a local copy blob something inside that class probably isn’t being copied into the list properly and causing problems when you want to access this later. You can either make copy constructors, or, easier, just use a pointer to a blob, i.e.

  
  
blob* newBlob = new blob();  
beatBlobs.push_back(newBlob);  
  

and then just make sure you delete the pointer when you pop_front():

  
  
blob* oldBlob = beatBlobs[0];  
beatBlobs.pop_front();  
delete oldBlob; // this keeps you from leaking memory.  
  

Also, code tags are sweet :slight_smile:

Thanks for the insight, Joshua. Accumulating memory leaks sounds like a possible offender.

Can you post your blob class?

As it would turn out blob is a struct and not a class. It seemed too simple to be made into a class. Could the use of a struct rather than a class be my problem?

  
struct blob {  
	float vertices[256][2];  
	int red, blue, green;  
};  

You can either make copy constructors, or, easier, just use a pointer to a blob, i.e.

Code:
blob* newBlob = new blob();
beatBlobs.push_back(newBlob);

What is the difference between what you are suggesting(with a pointer) and what I did(without a pointer) here:

  
                       blob newBlob;  
			for (int i = 0; i < 256; i++) {  
				float radians = (i / 256.0f * 360.0f) * DEG2RAD;  
				newBlob.vertices[i][0] = cos(radians) * (r + left[i] * scale) + a;  
				newBlob.vertices[i][1] = sin(radians) * (r + left[i] * scale) + b;  
			}  
			newBlob.red = ofRandom(0, 255);  
			newBlob.green = ofRandom(0, 255);  
			newBlob.blue = ofRandom(0, 255);  
			beatBlobs.push_back(newBlob);  

thanks again for your help,
gonna go make the struct to class + non-pointer to pointer changes
Jason

You’re allocating memory there:

  
  
float vertices[256][2];  
  

so when you copy it into the list, each instance, and all the memory that it contains, is getting copied around, possibly in weird ways. Also, in C++, structs and classes are pretty much the same, and generally I just use classes. Doesn’t matter a ton though. You can check on stackoverflow, this one kinda address it, but is a bit complicated: http://stackoverflow.com/questions/3376-…-n-a-stdmap

also, you can read here www.parashift.com/c+±faq-lite/ for more info on the difference between pointers and instances, it’s a very important thing to get your head around for writing code in C++.

Hey Joshua,

Im having a little trouble putting your suggestions into practice.

When I try to pass a pointer of a blob instead of and instance as you suggested:

  
blob *newBlob;  
			for (int i = 0; i < 256; i++) {  
				float radians = (i / 256.0f * 360.0f) * DEG2RAD;  
				newBlob->vertices[i][0] = cos(radians) * (r + left[i] * scale) + a;  
				newBlob->vertices[i][1] = sin(radians) * (r + left[i] * scale) + b;  
			}  
			newBlob->red = ofRandom(0, 255);  
			newBlob->green = ofRandom(0, 255);  
			newBlob->blue = ofRandom(0, 255);  
			beatBlobs.push_back(newBlob);  

I get this error:
testApp.cpp:53: error: no matching function for call to ‘std::list<blob, std::allocator >::push_back(blob*&)’
/usr/include/c++/4.2.1/bits/stl_list.h:763: note: candidates are: void std::list<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = blob, _Alloc = std::allocator]

I thought perhaps you made a typo and meant

  
beatBlobs.push_back(*newBlob)  

I added the asterisk and the project compiled, but eventually crashed the machine again. This might because I was unable to implement your suggestion for clearing the memory.

blob* oldBlob = beatBlobs[0];
beatBlobs.pop_front();
delete oldBlob; // this keeps you from leaking memory.

This doesn’t work because beatsBlob is a stl list and mot an array. So I tried

  
		blob* oldBlob = beatBlobs.front();  
		beatBlobs.pop_front();  
		delete oldBlob; // this keeps you from leaking memory  

.

and I got:

testApp.cpp:75: error: cannot convert ‘blob’ to ‘blob*’ in initialization

Any ideas about what I’m doing wrong?

Thanks! :smiley:
Jason

See if this helps

  
blob *newBlob;  

needs to be

  
blob *newBlob = new blob();  

beatBlobs will also need to be modified to store pointers (probably in testApp.h)

  
list<blob *> beatBlobs;  

Thanks jvcleave, I understand.

However, I think I managed to fix it a different way. Tell me if this makes sense.

I replaced the arrays in the blob definition with vectors:

  
class blob   
{  
public:  
	blob();  
	vector< vector<float> > vertices;  
	int red, green, blue;  
  
};  

leaving the list of instances(maybe a prob in the future???)

  
list<blob>			beatBlobs;  

and then appending the new blobs as follows:

  
			blob *newBlob = new blob();  
			beatBlobs.push_back(*newBlob);  
			delete newBlob;   

Since I used vectors instead of arrays and already deleted the dynamically created memory above, erasing blobs is simply:

  
for (list<blob>::iterator bb = beatBlobs.begin(); bb != beatBlobs.end(); ++bb) {  
			if (bb->red == 0 && bb->green == 0 && bb->blue == 0) {  
				bb = beatBlobs.erase( bb );  
			}  

Does that make sense? It hasn’t crashed since!

Should I change the list type from instances to pointers?

thanks for everyone’s help!
Jason