I am currently recoding srtcat()
from the standard C library and I have set up some checks to avoid overlap problems. The problem is that my program still enters the error handling.
Here is the code:
char *my_strcat(char *restrict dest, const char *restrict src)
{
size_t dest_len = 0, src_len = 0;
char *p = dest;
src_len = my_strlen(src);
if (!dest || !src)
return NULL;
dest_len = my_strlen(dest);
if (src >= dest && src < dest + dest_len) {
return NULL;
}
if (dest >= src && dest < src + src_len) {
return NULL;
}
while (*p != '\0') p++, dest_len++;
if (dest_len + src_len + 1 > sizeof(dest))
return NULL;
p = dest + dest_len;
while (*src != '\0')
*p++ = *src++;
*p = '\0';
return dest;
}
size_t my_strlen(const char *s)
{
size_t count = 0;
if (s != NULL) {
while (*s != 0) {
count++;
s++;
}
}
return count;
}
I tested this way :
int main(int argc, char **argv)
{
const char *src = "Hello";
char dest[100] = " world!";
char *test = my_strcat(dest, src);
printf("Src : %s Dest : %s\n", src, dest);
printf("Return adress : %p, Value : %s\n", test, test);
return 0;
}
According to gdb
:
if (src >= dest && src < dest + dest_len)
1: dest = 0x7fffffffda70 " world!"
2: src = 0x555555557004 "Hello"
3: dest_len = 0
4: src_len = 5
Src : Hello Dest : world!
Return adress : (nil), Value : (null)
Do you see the problem?
Following your suggestions I have modified the code like this:
char *my_strcat(char *restrict dest, const char *restrict src, size_t d_size)
{
size_t dest_len = 0, src_len = 0;
char *p = dest;
if (!dest || !src)
return NULL;
src_len = my_strlen(src);
dest_len = my_strlen(dest);
if (src >= dest && src < dest + dest_len) {
return NULL;
}
if (dest >= src && dest < src + src_len) {
return NULL;
}
while (*p != '\0') p++, dest_len++;
if (dest_len + src_len + 1 > d_size)
return NULL;
p = dest + dest_len;
while (*src != '\0')
*p++ = *src++;
*p = '\0';
return dest;
}
And in the main : char *test = my_strcat(dest, src, sizeof(dest));
But it still doesn't work :
Src : Hello Dest : world!
Return adress : 0x7fff74bc5650, Value : world!
Having tried to guide toward understanding this problem, it seems best to present what should be working code (for study.) Sometimes too many words merely muddle the situation:
char *my_strcat(char *restrict dest, const char *restrict src, size_t d_size) {
if( !dest || !src )
return NULL;
size_t src_len = strlen( src );
size_t dest_len = strlen( dest );
if( dest_len + src_len + 1 > d_size )
return NULL;
char *p = dest + dest_len;
while( (*p++ = *src++ ) != '\0' )
;
return dest;
}
int main() {
const char *src = "Hello";
char dest[100] = " world!";
printf("Src : %s Dest : %s\n", src, dest);
char *test = my_strcat( dest, src, sizeof dest );
if( test )
printf("Value : %s\n", test );
return 0;
}
Now, one can experiment by shrinking the size of dest
to something larger than " world!" but smaller than " world!Hello"... Perhaps 9 bytes???
And, now that the concatenation should be working (into a big enough buffer), adding the code to ensure there is no overlap of the actual character arrays. Known is the size of dest, and the length of src is measured.