0

重複の可能性:
c が宣言なしで文字列の初期化を許可するのはなぜですか?

私はこのかなり単純なコードを試しています:

#include<stdio.h>
void copy(char *,char *);
main() {
char *name;
char *surname;
printf("Enter name: ");
scanf("%s",name);

printf("%s",name);
}    

しかし、何らかの理由で、名前を入力して を押すEnterと、プログラムがハングし、「Program has stopped working」のようなメッセージが表示されます。ただし、2番目の文字ポインター宣言を削除するとchar *surname;、それは期待どおりに機能します。ここで何が問題なのですか?

4

4 に答える 4

3

ポインターにメモリを割り当てていないため、scanf未定義の動作である任意の未指定のメモリにアクセスします。

scanf に十分な大きさのメモリ ブロックへのポインタを渡す必要があります。

char s1[100], s2[100];

(100 で十分な場合)、またはmallocメモリ

char *s1 = malloc(100);
char *s2 = malloc(100);
if (!s1 || !s2) {
    // malloc failure
    exit(EXIT_FAILURE);
}
于 2012-10-27T12:35:51.793 に答える
2

未割り当てのメモリに書き込んでいます。つまりundefined behavior

ここで 2 つのことができます。

  1. 次のように、コンパイル時に文字の配列を固定サイズとして宣言しますchar name[100];(つまり、実行時にサイズを変更することはできません)。
  2. でmalloc()またはcalloc()関数をchar *name使用するためのスペースを割り当てますstdlib.h

いずれにせよ、ユーザーが割り当てたバイト数の入力のみを許可することを絶対確認する必要があります。そうしないと、悪いことが起こる可能性があります。

上記の境界を定義できなかった場合に悪人ができること (およびすること) に関する小さな研究は、ここにあります: http://www.cultdeadcow.com/cDc_files/cDc-351/

于 2012-10-27T12:35:30.300 に答える
1

メモリを割り当てておらず、その中に入れた文字列がプログラムのコードを台無しにしているからです。sscanfgetlineを使用してみてください:

#include <stdio.h>

int main()
{
  int nbytes = 100;
  char *my_string;
  int int1, int2, int3;
  int args_assigned;

  args_assigned = 0;

  while (args_assigned != 3)
    {
      puts ("Please enter three integers separated by whitespace.");
      my_string = (char *) malloc (nbytes + 1);
      getline (&my_string, &nbytes, stdin);
      args_assigned = sscanf (my_string, "%d %d %d", &int1, &int2, &int3);
      if (args_assigned != 3)
    puts ("\nInput invalid!");
    }

  printf ("\nThanks!\n%d\n%d\n%d\n", int1, int2, int3);

  return 0;
}

これをチェックしてください:

Cで可変長文字列のユーザー入力を読み取る

この :

http://en.wikipedia.org/wiki/Buffer_overflow

于 2012-10-27T12:36:59.647 に答える
1

ポインタを宣言し、有効なメモリ アドレスを指定しないと、ランダムなアドレスを指します。このポインターで読み書きすることはできません。ポインターは次のように使用する必要があります。

char s1[100],s2[100];
char * name=s1;
char * surname=s2;
于 2012-10-27T12:39:09.423 に答える