With:
char *x = malloc(1024);
strcpy(x, "asdf");
x = strdup(x);
free(x); // OK
free(x); // Segfault
If I just free it once, will I still be leaking? And if so, how to avoid it?
You leak memory because you forget the first pointer. Do it like this:
char * x = malloc(1024);
strcpy(x, "asdf");
char * y = strdup(x);
free(x);
free(y);