Manohar
Manohar

Reputation: 1330

Copying a string without using standard library

I have a noob question here, cannot understand whats wrong here. I have the following code here:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>  


void copyFrom(char * mStr, char * str); 


int main() {  

    char * srcStr = "Robert bought a good ford car";  
    char * dstStr = NULL;  
    copyFrom(srcStr, dstStr);
    printf("The string copied here is %s", dstStr);
    return 0;
}
void copyFrom(char * str, char * mStr)
{
    if(!mStr) {
        mStr = (char *)malloc((strlen(str)) + 1);
        if(mStr == NULL)
            return;
    }

    while(*mStr++ = *str++) {
        ;
    }

    mStr[strlen(str)] = '\0';
}

This does not copy the string, But if array is used instead of char pointer for dstStr, it all works fine.

Can you please tell me what is wrong here?

Upvotes: 2

Views: 1180

Answers (6)

Zan Lynx
Zan Lynx

Reputation: 54373

You need to return the value of mStr after you malloc it. Right now the return value of malloc and the pointer to your copy of the string disappears when you exit the function. It leaks the memory from malloc because it loses track of it.

Change your function to char* copyFrom(const char * str)

and then return mStr from that function. Then you can write dstStr = copyFrom(srcStr)

Now, POSIX C already has this function. It is called strdup.

Upvotes: 7

verbose
verbose

Reputation: 7917

In C, even pointers are passed by value. When you pass a pointer to a function, the function receives a copy--i.e., a new pointer that points to the same place as the pointer in the calling function.

So in your code, when you pass dstStr, you are passing a null pointer. mStr is a new null pointer. While you allocate memory for mStr, this memory is allocated to this new pointer, not to dstStr. So when your function returns, dstStr in the calling function is still NULL, and there is nothing pointing to the memory that was allocated in copyFrom(). You have a memory leak!

You need to pass dststr() as a two-level pointer in order to change what it points to in the calling function:

void copyFrom(char * str, char **dstStr)
{   
    char* mStr; 

    mStr = (char *)malloc((strlen(str)) + 1);
    if(mStr == NULL)
        return;


    while(*mStr++ = *str++) {
        ;
    }

    mStr[strlen(str)] = '\0';

    *dststr = mStr;

    return;
}

And of course your function declaration and call need to be changed accordingly. Your call would need to pass &dstStr as the argument, not just dstStr.

Upvotes: 3

Keith
Keith

Reputation: 6834

Rather than return, you can do pass the dest by reference:

void copyFrom(const char * src, char *& dest); 


int main() {  

    char * srcStr = "Robert bought a good ford car";  
    char * dstStr = 0;  
    copyFrom(srcStr, dstStr);
    printf("The string copied here is %s", dstStr);

    return 0;
}
void copyFrom(char * str, char *& mStr)
{
    if(!mStr) {
        mStr = (char *)malloc((strlen(str)) + 1);
        if(mStr == NULL)
            return;
    }
    char* it = mStr;
    while(*it++ = *str++)
    {
        ;
    }
    *it = 0;
}

Upvotes: 0

zahirdhada
zahirdhada

Reputation: 405

You can do this,

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void copyFrom(char * mStr, char * str);

int main() {
    char * srcStr = "Robert bought a good ford car";
    char * dstStr = NULL;
    dstStr = (char *)malloc((strlen(srcStr)) + 1);
    copyFrom(srcStr, dstStr);
    printf("The string copied here is %s", dstStr);
    return 0;
}

void copyFrom(char * str, char * mStr)
{
    while(*mStr++ = *str++) {
        ;
    }

    mStr[strlen(str)] = '\0';
}

Upvotes: 1

David Schwartz
David Schwartz

Reputation: 182885

char * dstStr = NULL;
copyFrom(srcStr, dstStr);
printf("The string copied here is %s", dstStr);

dstStr is NULL, the first line set it. While copyFrom allocates a string, it doesn't return that string to the caller. So your printf gets a NULL.

Upvotes: 2

Joel Falcou
Joel Falcou

Reputation: 6357

dstStr is not allocated so you're not puttign your data anywhere. Use malloc to allocate a proper memory block then copy.

The reason it works with array is that the string is stored on the stack with memory automatically allcoated for it.

Also this is C not C++ as C++ string handlign is done via std::string.

Upvotes: 0

Related Questions