2

ここで初歩的な質問がありますが、ここで何が問題なのか理解できません。ここに次のコードがあります。

#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 ポインターの代わりに配列を使用すると、すべて正常に動作します。

ここで何が間違っているのか教えてください。

4

6 に答える 6

7

malloc 後に mStr の値を返す必要があります。現在、malloc の戻り値と文字列のコピーへのポインターは、関数を終了すると消えます。追跡を失うため、malloc からメモリがリークします。

関数を次のように変更しますchar* copyFrom(const char * str)

その関数から mStr を返します。それからあなたは書くことができますdstStr = copyFrom(srcStr)

現在、POSIX C にはすでにこの機能があります。といいstrdupます。

于 2013-08-22T06:09:34.110 に答える
3

C では、ポインターも値渡しされます。関数にポインターを渡すと、関数はコピーを受け取ります。つまり、呼び出し元の関数のポインターと同じ場所を指す新しいポインターです。

したがって、コードで をdstStr渡すと、null ポインターが渡されます。mStr新しいヌルポインタです。にメモリを割り当てるとmStr、このメモリは ではなく、この新しいポインタに割り当てられますdstStr。したがって、関数が返さdstStrれたとき、呼び出し元の関数はまだ NULL であり、で割り当てられたメモリを指すものは何もありませんcopyFrom()。メモリ リークがあります。

dststr()呼び出し元の関数で指すものを変更するには、2 レベルのポインターとして渡す必要があります。

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ます。

于 2013-08-22T06:17:28.017 に答える
2
char * dstStr = NULL;
copyFrom(srcStr, dstStr);
printf("The string copied here is %s", dstStr);

dstStrは NULL で、最初の行で設定されています。文字列をcopyFrom割り当てますが、その文字列を呼び出し元に返しません。だからあなたprintfはNULLを取得します。

于 2013-08-22T06:11:35.720 に答える
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';
}
于 2013-08-22T06:14:26.757 に答える
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;
}
于 2013-08-22T06:16:28.203 に答える
0

dstStr は割り当てられていないため、データをどこにも置きません。malloc を使用して適切なメモリ ブロックを割り当ててからコピーします。

配列で機能する理由は、文字列がスタックに格納され、メモリが自動的に割り当てられるためです。

また、C++ 文字列処理は std::string を介して行われるため、これは C++ ではなく C です。

于 2013-08-22T06:06:53.973 に答える