不使用标准库复制字符串

时间:2013-08-22 06:03:20

标签: c++

我这里有一个noob问题,无法理解这里的错误。我在这里有以下代码:

#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';
}

这不会复制字符串,但如果使用数组而不是dstStr的char指针,那么一切正常。

你能告诉我这里有什么问题吗?

6 个答案:

答案 0 :(得分:7)

你需要在malloc之后返回mStr的值。现在,退出函数时,malloc的返回值和指向该字符串副本的指针将消失。它从malloc泄漏了内存,因为它失去了对它的追踪。

将您的功能更改为char* copyFrom(const char * str)

然后从该函数返回mStr。然后你可以写dstStr = copyFrom(srcStr)

现在,POSIX C已经具备此功能。它被称为strdup

答案 1 :(得分:3)

在C中,甚至指针都按值传递。当你将一个指针传递给一个函数时,该函数会收到一个副本 - 即一个指向调用函数中指针所在位置的新指针。

因此,在代码中,当您传递dstStr时,您传递的是空指针。 mStr是一个新的空指针。在为mStr分配内存时,此内存将分配给此新指针,而不是dstStr。因此,当函数返回时,调用函数中的dstStr仍为NULL,并且没有任何内容指向copyFrom()中分配的内存。你有内存泄漏!

您需要将dststr()作为两级指针传递,以便更改它在调用函数中指向的内容:

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;
}

当然,您的功能声明和调用需要相应更改。您的调用需要传递&dstStr作为参数,而不仅仅是dstStr

答案 2 :(得分:2)

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

dstStr为NULL,第一行设置它。虽然copyFrom分配了一个字符串,但它不会将该字符串返回给调用者。所以你的printf获得了一个NULL。

答案 3 :(得分:1)

你可以这样做,

#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';
}

答案 4 :(得分:0)

dstStr未分配,因此您不会在任何地方放置数据。 使用malloc分配适当的内存块然后复制。

它与数组一起工作的原因是字符串存储在堆栈中,内存自动为其涂层。

这也是C而不是C ++,因为C ++字符串handlign是通过std :: string完成的。

答案 5 :(得分:0)

您可以通过引用传递dest,而不是返回:

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;
}