3

私は次のことをしました:

char * copyact(char * from)
{
    return ++from;
}

int main()
{

    char *string = "school";
    char *copy;
    copy = copyact(string);
    printf("%s", copy);
}

これは印刷choolしていますが、main() で印刷しようとすると、アプリケーションがクラッシュする必要があるというのが私の考えです。スコープ ルールにより、パラメーター from は copyact 関数に対してローカルな変数です。私は from = from + 1; をやっています。その場所への住所を返します。main に戻ると、すべてのローカル変数を破棄する必要があるため、その場所に与えられたメモリは無効になるのではないでしょうか? なぜこれがまだ機能しているのですか?

明確化:文字列のアドレスを格納するポインタ &from にメモリ位置を割り当てませんか? 関数が終了するときに、有効なアドレスを保持しているポインタのアドレスも破棄しませんか? それとも、 return が実行されるまでに、それが指すアドレスが既に copy= に送信されているためですか?

4

3 に答える 3

2

関数は、その外部に既に存在するオブジェクトへの参照を取得するため、機能します。返される結果は単なる値です。コードから判断すると、先頭から1つずらした文字列へのポインタを返します。元の文字列が空の文字列の場合、おそらくクラッシュするでしょう。

于 2013-10-13T08:43:09.047 に答える
2

1. 未定義の動作はクラッシュではありません

まず第一に、メモリを使って悪いことをした場合 (変数が破棄された後に処理するなど)、結果は未定義の動作であり、これは「クラッシュ」とはまったく異なることを意味することを覚えておいてください。

未定義の動作は、(クラッシュを含む) あらゆることが起こり得ることを意味しますが、あらゆることが「何もない」ことを意味する場合もあります。実際、最悪の種類のバグは、未定義の動作がすぐには明らかな結果をもたらさず、100 万個の命令が後で実行されるコードの別の無関係で無害な部分でおかしな動作を引き起こすだけのものです。または、多数の視聴者の前で番組を上映する場合のみ。

したがって、未定義の動作はクラッシュではないことに注意してください。運がいいときだけのクラッシュです。

バグとクラッシュの違いを理解するのは早ければ早いほどよいのです。バグは敵であり、クラッシュは味方です (バグが明らかになるため)。

2. このコードは何も悪いことをしていません

この関数は を返し、char *この値 (ポインター) は、ローカル変数を事前にインクリメントすることによって計算されます。関数が返すと、ローカル変数は破棄されますが、関数がその(ポインター) を返すため、コードは完全に安全です。

関数が次のように定義されている場合、代わりに安全ではありませんでした

char *& copyact(char * from)
{
    return ++from;
}

この場合、戻り値はchar へのポインターへの参照でありfrom呼び出し元が返された参照にアクセスできるようになるまでに、それは既に破棄されていた参照を返します。

ちなみに、たとえばg++コンパイラは、変更されたバージョンをコンパイルすると警告を発します。

vref.cpp: 関数 'char*& copyact(char*)' 内:
vref.cpp:3:9: 警告: ローカル変数 'from' への参照が返されました

ただし、この場合でも、コードを実行すると確実にクラッシュすることは期待できないことに注意してください。たとえば、変更されたバージョンでバグのあるコードを実行しているコンピューターでは"school""chool".

あまり意味がありませんが、未定義の動作領域に入ると、これはごく普通のことです。

于 2013-10-13T09:22:07.073 に答える
1
char * copyact(char * from)
{
    return ++from;
}

    char *string = "school"; 
    char *copy;
    copy = copyact(string);

にファーム ポイントを作成しています"school"。これは既にメモリに存在します

そして、あなたは「学校」を指す+1から返されます

たとえば、その場合は戻ってはいけません。

char * copyact(char * from)
 {   
  char a[10];                 //declared array, has automatic scope.
  return a;                  // you should not return a and can't be accessed outside of function. 
 }
于 2013-10-13T09:05:48.120 に答える