I’m porting a program that works with Ubuntu 8.04 (gcc version 4.2.4) to 10.04 (gcc version 4.4.3). I have the following code:
#include <stdio.h>
#include <string.h>
int main(void) {
char p[100] = "////abcd";
char *t;
/* Remove duplicate slashes, saving only one of them */
while (t = strstr(p, "//"))
strcpy(t, t + 1);
printf("%s\n", p);
return 0;
}
The result should be /abcd, which it is with gcc 4.2.4. With 4.4.3, the output is /accd.
Can you suggest me a code change that will give the correct output using both versions of gcc, and preferrably explain what is going on here.
Thanks in advance!
You’ve just been lucky.
From the
strcpydocumentation:The strings overlap in your case, your program invokes undefined behavior.
A possible reason why it used to work but no longer does is that
strcpycould have been implemented as a builtin by GCC likememmove(i.e. safe in this situation), but this changed to a non-safe version for performance reasons. (This is pure speculation.)To fix it, use
memmoverather thanstrcpy, with something like:That’s not terribly efficient, but it will work portably –
memmovehas to handle overlapping memory areas.