Q:

Appending a char to a C-String

My following code works fine so far, but last time I tried to compile & execute it, it crashed for no reason. I tried to reproduce the error but it doesn't happen anymore after I tried it again and the code works. 
Any clue why the program crashed just only one single time?
int main(void)
{
       char *aStr = "testing";
       char *str = (char *) malloc(sizeof(char)*(sizeof(aStr)+1));
       strcpy(str, aStr);

       addChar(str, 's');
       printf("%s\n", str); //output should be "testings"
}

void addChar(char *str, char c)
{
     str = (char *) realloc(str, (sizeof(str)+2)*sizeof(char));
     str[sizeof(str)] = c;
     str[sizeof(str)+1]= '\0';
}

I know that's kind of a complicated way to do it but I wanted to know why it crashed.
EDIT:
    sizeof(str) should have been strlen(str)

A:

I see three main problems in your code, any of which may have caused a crash:

You're missing your #includes. In particular, #include <stdlib.h> is missing, which means malloc is undeclared. If malloc were declared, you wouldn't need those (char *) casts.
In C89/C90 mode, C compilers just assume undeclared functions return int. On a 64-bit platform with 8 byte pointers and 4 byte int, this would cause calls to malloc to be miscompiled. In particular, this can corrupt the returned pointer (e.g. by truncating it to 32 bits), which can crash the program.

In sizeof(aStr) and sizeof(str) you're taking the size of a pointer (usually either 4 or 8 bytes), which is not related to the length of the string they're pointing into. You need to use strlen instead.
On a 32-bit platform, you'd allocate just 5 bytes for an 8 byte string, which means strcpy(str, aStr); could crash (or corrupt memory enough for the next realloc to crash).

str = realloc(str, ...) in addChar is pointless. str is a local variable in the function; str in main still points at the old memory location. To make this work, you need to return the new pointer from addChar or make addChar take an output parameter (where it can store the result).
If realloc is unable to resize the allocation in place, this will invalidate the old pointer, making it an indeterminate value. If it happens to overwrite the old memory with non-NUL bytes, this could make printf crash when it tries to output (what it assumes to be) the string.

