2017-10-28 15 views
-3
#include <stdio.h> 
#include <string.h> 

char lists[10][25]; 
char name[10]; 

void main() 
{ 
    scanf("%s" , lists[0]); 
    memcpy(name , lists[0], 25); 

    printf("%s\n" , name); 
} 

私のように入力を与えたとき、私は今10 として文字列「名前」のサイズを事前に定義しています:memcpy関数の動作についての説明は?上記のコードで

入力 -

abcdefghijklmnopqrstuvwxy私が得た出力が同じでした文字列:abcdefghijklmnopqrstuvwxy

私は出力を次のようにしてください:abcdefghij ???

配列のサイズが10に制限されていても、これはどのようになりますか?

+3

これは*未定義の動作*の例です。これは何かが起こる可能性があることを意味します。それが必要な作業プログラムを含む。 – klutt

+1

あなたのコードは非常に基本的なUBの線の外に色付けされています。あなたがそれを爆破してディスクを再フォーマットするには、より多くの色が必要です。 2つの変数宣言を入れ替えてみるとよいでしょう。 –

+1

ほとんどの言語は、プログラマがあなたに配列の終わりを越えて書き込むのを防ぎます。 Cはしません。これを防ぐのはあなたの責任です。 – jarmod

答えて

1

割り当てられたメモリのサイズが分からないため、余分なデータが書き込まれた場所が離れてしまいます。別のプラットフォームで使用したり、別のコンパイラーを使用したり、異なる最適化設定を使用したりすることはできません。

sizeパラメータをmemcpy()に渡す場合は、宛先メモリのサイズを考慮することをお勧めします。

文字配列を使用しているときに、メモリを超過しないように安全な場合は、strncpy()を使用できます。末尾にNULLという末尾を挿入します。

+0

私の利用可能なメモリブロックが10だったら、これは起こりませんでしたか? – Jamzy

+1

いいえ、メモリが25の場合、問題はありません。 Cはメモリの割り当てや書き込みなどに注意を払ってプログラマに依存します – Steve

+0

私は利用可能な物理メモリがわずか10であると言いましたが、余分なメモリを見つけることができず、エラーや何かが発生しました!右 ?? – Jamzy

0

まず、配列はポインタです。 C言語では、Javaのような長さチェックはありません。

char a[2];と書くと、OSはメモリに2文字分のスペースを与えます。 例えば、メモリは

|1|2|3|4|5|6|7|8|9|10|11|12| 
a 

aa[0] = 0;write 0 to the address a + offset 0を意味する、*(a+0) = 0と等しいアドレス1へのポインタであるとします。

割り当てられていないアドレスに書き込もうとすると、予期しないことが起こる可能性があります。例えば

、その後a[2] = 0b[0] = 0に等しい私たちはchar a[2];char b[2];を持っていると言うと、メモリマップが

|1|2|3|4|5|6|7|8|9|10|11|12| 
a b 

であることができます。しかし、このアドレスが他のプログラムのアドレスであれば、セグメント化エラーが発生します。あなたが言ったデータの他のサイズに

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

char a[4]; 
char b[4]; 

void main() 
{ 
    scanf("%s" , a); // input "12345678" 
    printf("%s\n" , b); // print  "5678" 
} 

memcpyアドレスからだけコピー:

は、プログラムを(それはコンパイラの最適化なしで動作する場合があります)試してみてください。

あなたの例では、アクセスしたすべてのアドレスがプログラムに割り当てられている場所(自分のメモリページ内)にあるため、あなたは寂しかったです。

C/C++では、メモリを正しく処理する責任があります。また、文字列は文字\0で終わるので、配列char str[10];の中には、通常、先頭に9文字あり、\0があります。

+1

私はあなたがここに入力ミスを持っていると思います: "a [0] = 0; *(a + 1)= 0と等しい、0をアドレス+オフセット0に書き込むことを意味します。 – MFisherKDX

+0

はい、もちろんです。ありがとうございました。 – GramThanos

+0

"| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | ab次に、a [2] = 0はb [0] = 0 "あなたがこの行動に頼っているなら、あなたは傷つく世界のためにいるのです。コンパイラ/オプティマイザが何をするかは分かりません。 – MFisherKDX

関連する問題