1

次のコードの実行中に、プログラムが予期せずクラッシュします。

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

int main(){

    char *str = NULL;
    strcpy(str, "swami");
    printf("%s", str);
    return 0;
}

しかし、私がこれを好きなら:

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

int main(){

    char *str;
    strcpy(str, "swami");
    printf("%s", str);
    return 0;
}

このコードは正常に動作し、正しい出力を生成します!

gcc コンパイラ (codeblocks IDE) を使用しています。また、どちらのコードも DevCpp でプログラム クラッシュを引き起こします。なぜそうなのか誰か説明してくれませんか!?

4

5 に答える 5

23

NULLポインターに書き込むことはできません。

2 番目のケースでは、ポインタがプログラムのメモリ内の有効な場所にランダムに初期化されました。それがあなたがそれに入ることができる理由ですstrcpy

両方のプログラムを次のように変更します

str = malloc(size)

callocまたは の前にあるオプションstrcpy。(sizeは予約するスペースのサイズです。)

コメントに従って、strto be char str[6](または more) の宣言を変更することもできます。

最終編集: プログラムのメモリとポインターを示すこの写真を紹介します。

ここに画像の説明を入力

灰色の領域と赤色の領域は禁止されています (書き込みや読み取りはできません。上の灰色の領域はカーネル メモリ用で、その他はまだ再利用されていない領域です)。一番下の赤い部分がスペシャル0ページです。あなたNULLはこれを指しているので、あなたのプログラムは失敗します。0str = NULL

何も割り当てないと、strランダムにポイントすることになります。まだ赤い領域または灰色の領域を指している可能性があります->プログラムは失敗します。緑または青 (両方の色合い) の領域を指すことができ、プログラムが機能します (読み取り専用の場所を指していて、そこに書き込む場合を除く)。ポインターに領域を割り当てると、緑色の領域を指すようになり、上部に拡大されます。

もう 1 つのオプションはstr[6]、スタック領域を下に拡大します。すべてのローカル変数はスタックに予約されたスペースを持ち、 、 、およびその他の仲間で割り当てられたすべてのスペースmallocreallocヒープcallocに入ります。

最後に、 との違いに関するブログ記事をご覧ください。char[]char *

PS: GNU 拡張機能を使用したい場合は、asprintf関数を調べることができます。文字列にスペースを割り当て、そこにコンテンツを書き込みます。

asprintf(&str, "swami");

また

asprintf(&str, "%d + %d == %d\n", 1, 2, 3);

ただし、移植性が必要な場合は、この機能を使用しないでください。

于 2012-09-18T18:02:54.607 に答える
4

どちらのバージョンでも、文字列をコピーするためのメモリを割り当てていないため、どちらも未定義の動作を呼び出します。に明示的に初期化strしたためNULL、最初のものはクラッシュするため、ほとんどのシステムでクラッシュするポインターをstrcpy逆参照します。NULL2 つ目は、str任意のメモリを指し、初期化されていないポインターがクラッシュする場合とクラッシュしない場合があることを逆参照します。

于 2012-09-18T18:05:08.740 に答える
2

にあるからNULLです。したがって、プログラムをクラッシュさせる無効なメモリアドレスを書き込もうとします。#define NULL ((void *)0)<stdlib.h>

于 2012-09-18T18:51:39.107 に答える
1

このリンクを読む

//destination =Pointer to the destination array where the content is to be copied.
char * strcpy ( char * destination, const char * source );

宛先をNULLに設定しているため、ソースをNULLにコピーしようとしています。それがクラッシュする理由です。代わりに文字列をコピーするために、メモリを脇に設定する必要があります。

int main(){
      char *str=malloc(6);  //enough for "swami"+'\0'
      strcpy(str, "swami");
      printf("%s", str);
      return 0;

}

于 2012-09-18T18:06:26.477 に答える
1

strcpyコピーするだけで、スペースは生成されません。

最初のケースでは、コードセグメントの先頭に文字列を書き込もうとしました。これは良い考えではありません。

2番目のケースでは、どこかに文字列を書き始めましたが、クラッシュしなかった場合は、運が良ければ、コンパイラの助けになるかもしれません。

次のいずれかを実行する必要があります。

a。メモリの割り当て:str = new char[10]
b。strdupwitchを使用して、文字列を新しい場所に複製します。

于 2012-09-18T18:07:52.000 に答える