简体   繁体   中英

Implementing strcat() using pointers

I am reading K&R and trying to do the excercise involving writing a version of strcat (attach one string to the end of the other) using pointers. This is what I have:

#include<stdio.h>
void mystrcat(char *s,char *t)
{
    while(*s++);
    *s--;
    while(*s++ = *t++);
}

int main()
{
    int size = 1024;
    char *s1, *s2;
    s1 = malloc(size);
    s2 = malloc(size);
    s1 = "Hello ";
    s2 = "World";
    mystrcat(s1,s2);
    printf("%s",s1);
    return 0;
}

The program runs but crashes straight away, not very experienced with pointers so can't work out the error.

The problem is here:

s1 = malloc(size);
s2 = malloc(size);
s1 = "Hello ";
s2 = "World";

You have allocated space for s1 and s2 , but instead of using it, you are making them point to string literals. These string literals are stored in a non-writable place of the memory (ie, you should not mess with it).

In short, you have to change your code to:

s1 = malloc(size);
s2 = malloc(size);
strcpy( s1, "Hello " );
strcpy( s2, "World" );

Now you are using the allocated space. Hope this helps.

EDITED: you also have a problem here:

void mystrcat(char *s,char *t)
{
    while(*s++);
    *s--;
    while(*s++ = *t++);
}

The second line should be s-- , instead of *s-- . *s-- would decrease the pointer s and access that new position. You don't actually need to dereference the pointer just to decrease it. You just want the pointer to point to a position before it is pointing to now. That's simply s-- .

s1 = "Hello ";

Now s1 is pointing at a read-only array of 7 characters storing the literal "Hello ". You've lost the pointer to the allocated 1024 characters that s1 was pointing at before. So your attempt to append to s1 is illegal.

Try maybe strcpy(s1, "Hello "); instead.

You made another mistake in *s-- . Pointer s is out of the buffer, and you shouldn't dereference it.

void mystrcat(char *s,char *t)
{
    while(*s++);
    s--;
    while(*s++ = *t++);
}

You can't copy a string by simple assignment.

If you want to copy "Hello " into a memory allocated with malloc, you need to copy the string into that block of memory:

s1 = malloc(size);
s2 = malloc(size);
strcpy(s1, "Hello ");
strcpy(s2, "World");

Direct assignment doesn't work with arrays.

"Hello " is essentially a char array.

Also, like someone said in the comments, "Hello " is allocated in a read only section of the code (Since it's allocated during compile time), so when you used your assignment, you actually redirect s1 to a read-only location, and when you try to write in a read only location, you're going to have a bad time.

First of all the function would look better if to define it the following way

char * mystrcat( char *s1, const char *s2 )
{
    char *p = s1;

    while( *s1 ) ++s1;
    while( *s1++ = *s2++ );

    return p;
}

The standard C function strcat returns pointer to the destination string.

As for the main then there are memory leaks because at first s1 and s2 are set to the addreses of the allocated memory and then they are are reassigned by the addresses of first characters of the string literals.

And moreover string literals in C and C++ are immutable. Any attempt to modify a string literal results in undefined behaviour of the program.

You could write instead

int size = 1024;
char *s;

s = malloc(size);
s[0] = '\0';

mystrcat( s, "Hello " );
mystrcat( s, "World" );

printf( "\"%s\"\n", s );

Or even you could write in one line

printf( "\"%s\"\n", mystrcat( mystrcat( s, "Hello " ), "World" ) );

You allocate memory for the strings, but then overrides it and lose the reference to this memory:

// allocate memory
s1 = malloc(size);
s2 = malloc(size);
// assign another address, e.g. lose the pointer
s1 = "Hello ";
s2 = "World";

You should copy the string to the allocate memory:

// allocate memory
s1 = malloc(size);
s2 = malloc(size);
// copy the string into it
strcpy(s1, "Hello ");
strcpy(s2, "World");

Also, it is a good practice to always free the memory you allocate after you are done with it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM