malloc vs realloc

Why when using realloc, john is reversed 3 times but not the other 2 names ? But if I use malloc, then the 3 names are reversed correctly ? (but then there is a memory leak)

How can I reverse all 3 names without a memory leak ?

char *BUFFER = NULL;

char *STRREVERSE(const char *STRING)
{
	BUFFER = (char *)realloc(BUFFER, strlen(STRING) + 1);

	size_t COUNT = 0;
	size_t LENGTH = strlen(STRING) - 1;

	while(COUNT <= LENGTH)
	{
		BUFFER[COUNT] = STRING[LENGTH - COUNT];

		COUNT++;
	}

	BUFFER[COUNT] = '\0';

	return BUFFER;
}

int main(void)
{
	printf("%s\n%s\n%s\n", STRREVERSE("john"), STRREVERSE("jack"), STRREVERSE("jill"));

	return 0;
}
#include <string.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

char *
strrev(char *src)
{
   char *p=src;
   char *q=strchr(src,'\0');
   char tmp=0x0;
   
   for(q--; q>p; q--,p++)
   {
      tmp=*q;
      *q=*p;
      *p=tmp;
   }
   return src;
}


int main()
{
    char one[12]={0x0};
    char two[12]={0x0};
    char three[12]={0x0};
    strcpy(one, "jack");
    strcpy(two, "jill");
    strcpy(three, "john");
    printf("%s\t %s\t  %s\n", strrev(one), strrev(two), strrev(three));
}

The way you set up your code, you were sending const strings to the reverser.
You had to call something like strdup() - automagic way to duplicate strings - or malloc or realloc.

In that case: You need to have separate objects for each call to strrev. The objects have to be created in the calling routine not the strrev routine. This is because you called all three in one function call to printf().

You also could have used printf() free() printf() free().. using your malloc code.

---------- Post updated at 20:45 ---------- Previous update was at 18:36 ----------

Revisiting this: you may want to read up on the concept of a sequence point in C.

I have just modified the single line in your program.
Try with the following code.

char *STRREVERSE(const char *STRING)
{
        char *BUFFER = NULL;
        BUFFER = (char *)realloc(BUFFER, strlen(STRING) + 1);

        size_t COUNT = 0;
        size_t LENGTH = strlen(STRING) - 1;

        while(COUNT <= LENGTH)
        {
                BUFFER[COUNT] = STRING[LENGTH - COUNT];

                COUNT++;
        }

        BUFFER[COUNT] = '\0';

        return BUFFER;
}

int main(void)
{
        printf("%s\n%s\n%s\n", STRREVERSE("john"), STRREVERSE("jack"), STRREVERSE("jill"));

        return 0;
}

In your program you have declared the char pointer BUFFER as a global pointer.
And you are calling the function in printf().
printf() is right associative.So STRREVERSE("jill") will be called first then STRREVERSE("jack") then STRREVERSE("john").
So finally the pointer BUFFER will have the reversed string of john only.
And The function STRREVERSE is returning char pointer(char *).
So the return value of the three function calls will be pointing the same address.(address of BUFFER).
BUFFER contains reversed string of john only.
So the value "nhoj" will get printed for three times.
So I have declared the BUFFER as a local pointer.

According to Valgrind, your code has a memory leak:

==31733== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 8 from 1)
==31733== malloc/free: in use at exit: 15 bytes in 3 blocks.
==31733== malloc/free: 3 allocs, 0 frees, 15 bytes allocated.

Consider sequence points, which are really your problem in your code - how to know when an operation will take place.

Ah really? Unless I am mistaken, the ANSI-C standard leaves the order of parameters evaluation up to the compiler ("it's unspecified"). This can be left-to-right, or right-to-left or anything else the compiler may find convenient.

Cheers,
Lo�c.