1
votes

I am having trouble trying to implement a custom strcpy function which is supposed to handle cases where the src string is larger than the destination string. Here I have provided some code so that you guys can see the entire function. My issue is that every time I increment *dest, it goes into a null address despite the fact that I have allocated enough memory to fit all of src in it. This causes the a segmentation fault in (double pointer)dest = *src. dest is stored as a char** because in reality, the argument that has to be passed is another string that is possibly of a smaller size than src, and I wish to overwrite *dest as safely as I can.

int customStrCpy(char** dest, char* src){
    int strlen1 = strlen(*dest), strlen2 = strlen(src);
    if(strlen1 < strlen2){
        //Creates a dynamically allocated array that is big enough to    store the contents of line2.
        *dest = calloc(strlen2, sizeof(char));
        char* backup_str = *dest;

        int copy_arrs;
        for(copy_arrs = 0; copy_arrs < strlen2; copy_arrs++){
            **dest = *src;
            *dest++; src++;
        }
        *dest = backup_str;
    }
    else strcpy(*dest, src);
}

In the end, (char**)dest is supposed to be pointing to the correct string.

3
strlen is returning number one less than you want. Mind the terminating \0. Also - is dest always pointing to a valid string when passed to this function?Eugene Sh.
strlen(*dest) will only tell you the current number of characters in *dest. If it has been allocated prior to the call of your method, you have no way of knowing how much space has been allocated without also passing that length into your method.FredK
You do realize that this function, even after you fix it, is basically a memory leak factory?Lee Daniel Crocker
If you replace the destination string with a newly allocated string, you should also free the original allocation.Barmar
Why not use strcpy() after calloc()? Also, why use calloc() instead of malloc(), if you're going to immediately overwrite it?Barmar

3 Answers

0
votes

Usually strcpy returns char * for "direct" use in other operations.

char *mysStrCpy(char **dest, const char *src)
{
    size_t len = strlen(src);
    char *tmpptr;

    *dest = malloc(len + 1);
    // or *dest = realloc(*dest, len + 1);
    if(*dest)
    {
        tmpptr = *dest;
        while(*tmpptr++ = *src++);
    }
    return *dest;
}
0
votes

You need to add 1 to the string length, to allow for the null terminator, and you should free the old contents of dest if you're allocating a new string. After you do this, you can do the same strcpy() as you do when you don't need to reallocate.

There's also no need for the int return type (unless you want to add error checking to malloc(), and return a status result). This function modifies an argument, it should be void.

void customStrCpy(char** dest, char* src){
    int strlen1 = strlen(*dest), strlen2 = strlen(src);
    if(strlen1 < strlen2){
        free(*dest); // Free the old string
        //Creates a dynamically allocated array that is big enough to store the contents of line2.
        *dest = malloc(strlen2+1);
    }
    strcpy(*dest, src); // or memcpy(*dest, src, strlen2+1);
}
-1
votes
 *dest++;

increments dest, not the pointer dest points to. You want:

(*dest)++;

ps: there are better ways to accomplish what you are after....