I'm trying to replicate the function strcat. The problem is that my array src is being modified even though I'm just use it to copy.
#include <stdio.h>
char *ft_strcat(char *dest, char *src)
{
int i = 0;
int c = 0;
while (dest[i] != '\0')
i ;
while (src[c] != '\0')
{
dest[i] = src[c];
c ;
i ;
}
dest[i] = '\0';
return dest;
}
int main(void)
{
char src[] = "_And Good Bye";
char dest[] = "Hello World";
char *ptr;
printf("\nString 1: %s\nString 2: %s\n", src, dest);
ptr = ft_strcat(dest, src);
printf("\nAfter strcat function.\nString 1: %s\nString 2: %s\n", src, dest);
return 0;
}
Output:
String 1: _And Good Bye
String 2: Hello World
After strcat function.
String 1: And Good Bye
String 2: Hello World_And Good Bye
After I run ft_strcat(dest, src)
, my char src
looses the character, "_"
. I don't understand why if I only use it to be copied.
I expect that src
is not modified.
CodePudding user response:
dest
has exactly enough memory to store "Hello World"
. When you append src
to it you're overwriting adjacent memory. That adjacent memory happens to contain src
. There's no guarantee that it will, but stack memory is often allocated this way.
For example, if I print out the memory address of src
and dest
I see...
printf("src: %p\ndest: %p\n", &src, &dest);
src: 0x7ffeea74e31a
dest: 0x7ffeea74e30e
The memory looks like this.
001111111111111111
ef0123456789abcdef
Hello World0_And Good Bye0
^ ^
dest src
When you concatenate src onto dest you overwrite the adjacent memory resulting in...
001111111111111111
ef0123456789abcdef
Hello World_And Good Bye00
^ ^
dest src
You need to allocate dest
to have enough space.
// "Hello World" "_And Good Bye" null byte
char dest[25] = "Hello World";
In a real program you'd allocate dest as dynamic memory and reallocate it to have enough space.
char *dest = malloc(12);
strcpy(dest, "Hello world");
dest = realloc(dest, strlen(dest) strlen(src) 1);
CodePudding user response:
The actual type of a string literal in C is char [N]
, wherein N
is the minimum amount of space required to store the characters of the string, including the null terminating byte.
In the case where you use a string literal to initialize an array of an unknown size (char foo[] = ...
), the resulting array is given the same typing as the string literal.
So in,
char src[] = "_And Good Bye";
char dest[] = "Hello World";
src
will have the type char [14]
, and dest
the type char [12]
.
Knowing this, it becomes obvious that dest
does not have enough room to append the contents of src
(zero excess memory, in fact). Care must always be taken to guarantee that there is enough room, otherwise you risk Undefined Behavior.
At a minimum, you would need char dest[25]
, though it may be prudent to drastically oversize your destination buffer.
char dest[512] = "Hello World";
const char *src = "_And Good Bye";
Initializing dest
in this way fills the rest of its memory with zeroes.
CodePudding user response:
For starters the function should be declared at least like
char *ft_strcat(char *dest, const char *src);
because the source string is not changed within the function.
Within the function you are trying to append the source string to the end of the destination string but the array that contains the destination string has no enough memory to accommodate also the source string, See the declarations of the arrays
char src[] = "_And Good Bye";
char dest[] = "Hello World";
You need to enlarge the array dest
.
For example you could write
char src[] = "_And Good Bye";
char dest[ 2 * sizeof( src )] = "Hello World";
Objects of the type int in general are unable to store all possible lengths of strings. For example the function strlen
or the operator sizeof
return values of the type size_t
In fact the declarations of the variables i
and c
int i = 0;
int c = 0;
are redundant within the function.
The function can look the following way
char * ft_strcat( char *dest, const char *src )
{
char *p = dest;
while ( *p ) p;
while ( ( *p = *src ) != '\0' );
return dest;
}
CodePudding user response:
Try to use Const modifier in source parameter. that's my first point.
char *strcat(char *destination, const char *source)