2

次のコードでは、文字列 "12345678901234567890" を共用体型の変数に完全にコピーすることはできません。これは私を本当に混乱させますか?

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

typedef union
{
    int i;
    long l;
    float f;
    double d;
    void *v;
    char *s;
    char c;
 } UType;

UType NewUType_s(char *s)
{
     UType temp;
     strcpy(temp.s, s);      // If we print temp.s and s here, both of them are "12345678901234567890
     return temp;
}

int main()
{
    UType m;
    m = NewUType_s("12345678901234567890");
    printf("%s\n", m.s);

    return 0;
 }

結果は: 1234567890123456 といくつかの特殊文字?

この問題の解決策は次のとおりです。

  • 解決策 1: malloc()m に使用します。

  • 解決策 2:NewUType_sスタイルをポインター関数に変更するUType *NewUType_s(char *s);と、すべてが正常に機能します。

しかし、上記のプログラムが正しい結果をもたらさない理由を誰かが知っていますか?

4

2 に答える 2

5

このコードの問題は、初期化されていないポインターに書き込む動作が未定義でtemp.sあることです。文字列をコピーできるメモリ ブロックが割り当てられていないためstrcpy、プログラムが所有していないメモリに書き込みます。

このコードの修正は簡単です。次のように、コピーする前にメモリを割り当てます。

UType NewUType_s(char *s)
{
     UType temp;
     temp.s = malloc(strlen(s)+1);
     strcpy(temp.s, s);
     return temp;
}

もちろんfree、メモリリークを避けるためにメモリが必要です。

于 2013-09-02T18:52:02.240 に答える
2

宛先配列が必要なstrcpyを呼び出しています。の値にはUTypeのみが含まれますchar*が、これは (初期化されていない場合) メモリ内のランダムな場所を指します。新しい文字列を割り当て、それへのポインタを返すstrdupが必要な場合があります。

UType NewUType_s(const char *s)
{
     UType temp;
     temp.s = strdup(s);
     return temp;
}
于 2013-09-02T18:52:41.127 に答える