Help With Memory Leak

I am writing a FIFO buffer to output up to 12x lines of status to a TFT display.

The array of pointers I am using is sent in, and the new data is pushed onto the array. I am using strdup() in order to move the data around and I am running out of SRAM on a MEGA quite fast; like after 5 or 6 pushes.

Can anyone help me with an alternative to strdup or a better way to free() the memory?

#define SCREEN_BUFFER_SZ 12
char *tftBuffer[SCREEN_BUFFER_SZ]={0};
...
in setup:

initBuffer(tftBuffer);

somewhere in loop:

pushBuffer(tftBuffer,"Serial Command Received...");

void initBuffer (char** data) {
	
	for (int i=0; i < SCREEN_BUFFER_SZ; i++) {
		data[i]=" ";
	}
}

void pushBuffer (char** data, char* str) {
	char* localBuffer[1];
	char* localBuffer2[1];
	int x,y;
	
	// clear out previous characters
	for (int i; i < SCREEN_BUFFER_SZ; i++) {
		x = 150 - (10*i);
		y=20;
		Tft.drawString((char*) data[i],x,y,1,BLACK);
	}
	
	for (int i=SCREEN_BUFFER_SZ-1; i>=0; i--) {	
		if (i==11) {	
			// save existing data[11]
			localBuffer[0]=strdup(data[i]);
			// insert new string @ data[11]
			//localBuffer2[0]=strdup(str);	
			data[i]=strdup(str);		
	    } else {
			// copy existing data n
			localBuffer2[0]=strdup(data[i]);	
			// insert n-1 data @ n
			data[i]=strdup(localBuffer[0]);			
		    localBuffer[0]=strdup(localBuffer2[0]);
		}			
	}
	//free(str);
	free(localBuffer[0]);
	free(localBuffer2[0]);
}

Here is the terminal data, all I am doing is sending in SERIAL commands to my code:

Boomer is online @ 10.0.0.177
Serial Command Received
Free Ram: 5777
Serial Command Received
Free Ram: 5570
Serial Command Received
Serial Command Received
Serial Command Received
Free Ram: 4499
Serial Command Received
Free Ram: 3992
Serial Command Received
Free Ram: 3410

	char* localBuffer[1];
	char* localBuffer2[1];

What possible benefit is there to a one element array vs. a scalar variable?

You have three calls to strdup() and two calls to free(). The number of calls to strdup() and the number of calls to free() need to match, or you WILL leak memory.

If you're just attempting to move data around, wouldn't memcpy be a more direct approach?

hello.
strdup() is written as-

char *strdup (const char *s) {
    char *d = malloc (strlen (s) + 1);   // Allocate memory
    if (d != NULL) strcpy (d,s);         // Copy string if okay
    return d;                            // Return new memory
}

you can see there is a dynamic memory allocation of tftbuffer size inside the for loop. and allocation is SCREEN_BUFFER_SZ times.

and you are not releasing it outside the loop.
thats why memory is leaking.

Don't duplicate or copy data - the Arduino has very little memory. Just change the indexes to it.

If you really do need a copy of something - perhaps because you want to change it without affecting the original - just copy it into an existing pre-defined location.

...R

Yes, I was not thinking clearly. All I need to do is shuffle pointers, no malloc needed...

void pushBuffer (char** bufferData, char* str) {
	char* localBuffer;
	char* localBuffer2;
	int x,y;
	
	// clear out previous characters
	for (int i; i < SCREEN_BUFFER_SZ; i++) {
		x = 150 - (10*i);
		y=20;
		Tft.drawString((char*) bufferData[i],x,y,1,BLACK);
	}
	
	for (int i=SCREEN_BUFFER_SZ-1; i>=0; i--) {	
		if (i==11) {	
			// save existing data[11]
			localBuffer=bufferData[i];
			// insert new string @ data[11]
			//localBuffer2[0]=strdup(str);	
			bufferData[i]=str;		
	    } else {
			// copy existing data n
			localBuffer2=bufferData[i];	
			// insert n-1 data @ n
			bufferData[i]=localBuffer;			
		    localBuffer=localBuffer2;
		}			
	}
}