Help with Malloc...

03 Nov 2011

Hi all..

I was looking for a simple substring type routine.. and I found one on the internet and it's nice.

I'm not much of a C programmer, and it has a malloc in the middle of it, and mallocs scare me, incase they are memory leaks.

can I ask..

a) is it ?! b) if it is, how do I stop it being one. (with a free somewhere? but where?)

at the minute I'm using it to trim a string to be printed on an LCD, soon it'll be a "teletyper" (when I put a loop on the call to it.)

How I call it:

void teletype(char* text, int row) {
    lcd.locate(0,row);
    lcd.printf("                ");
    lcd.locate(0,row);
    //loop will go here
    lcd.printf(left(text,2));
}

The function with the malloc;

char* left(string Source,int NewLen) {

	char* result;
	char* temp;
	if (NewLen <=0) 
		NewLen =1; /* Minimum length */

	result = (char*)malloc(NewLen + 1); /* +1 = DFTTZ! */
	*result=' ';   /* default for unassigned strings */
	temp=result;
	if (Source && *Source)  /* don't copy an empty string */
	{
		while (NewLen-- >0)
			*temp++=*Source++;
	}
	else temp++;
	*temp='\0';
	return result;
}

03 Nov 2011
it will allocate a new buffer for every call. So you have to free() the result every time once you're done with it.
i.e.
char* a = left(...);
doSomething(a);
free(a); a = NULL;
and that's all (the a=NULL isn't mandatory, just a reminder that you aren't allowed to refer to "a" once it's been free()d).
03 Nov 2011

many thanks for looking at it for me....

so is my

lcd.printf(left("some text",2));

a memory leak ?

as I just push the output to the LCD, so I never get a chance to free anything.

04 Nov 2011
yes it is.
And 
char* a = left("some text",2);
lcd.printf(a);
free(a);
fixes it.
04 Nov 2011

You could pass in a pointer to the buffer of the appropriate size to your left() routine, fill it in with the required left most characters, and return this passed in buffer pointer. This would remove the need for malloc().

#include "mbed.h"

char* left(char* pDest, const char* pSource, size_t OutputSizeInChars)
{
    char* pReturn = pDest;
    
    while(OutputSizeInChars-- > 1 && *pSource)
    {
        *pDest++ = *pSource++;
    }
    *pDest = '\0';
    
    return pReturn;
}

int main() 
{
    char FiveCharBuffer[5+1];  // Add 1 for NULL terminator.
    
    printf("Start\n");
    printf("'%s'\n", left(FiveCharBuffer, "1234567890", sizeof(FiveCharBuffer)));
    printf("'%s'\n", left(FiveCharBuffer, "12345", sizeof(FiveCharBuffer)));
    printf("'%s'\n", left(FiveCharBuffer, "1234", sizeof(FiveCharBuffer)));
    printf("'%s'\n", left(FiveCharBuffer, "", sizeof(FiveCharBuffer)));
    printf("Done\n");
    
    for(;;)
    {
    }
}
04 Nov 2011

many thanks..

I'm used to Java where we have a garbage collector, so anything that has no existing pointers to it is automatically garbage collected. So I'm not used to memory leaks !

Many thanks for all your help/explanations,

cheers,

Dave.