

C言語でmemcpyを使った以下のような配列コピーのコードで  
**以下のコードではbufの先頭アドレスから一つずらしたところにコピーすることで、コピー先とコピー元をあえて重複させて未定義動作を引き起こそうと思ったのですが。**

・これは適切な未定義動作の例になっているのか自分でもよくわかりません。またこれがなぜこのような結果になるのか簡単にでも教えていただきたいです。  
・また見様見真似で書いたコードなのですがもっと簡単なコードがあればぜひ教えていただきたいです

[code]

    #include <stdio.h>
    #include <string.h>
    
    void* memcpy(void *dst,const void *src,size_t n){
            size_t i;
            char *p1=dst;
            const char *p2=src;
    
            for(i=0;i<n;++i){
                    *p1=*p2;
                    ++p1;
                    ++p2;
            }
    }
    
    int main(void){
            char buf[]={0,1,2,3,4};
            char buf2[5];
    
            memcpy(buf+1,buf,sizeof(buf));
    
            for(int i=0;i<sizeof(buf);++i){
                    printf("%d\n",buf[i]);
            }
    
            return 0;
    }
    
[/code]

結果は以下のようになりました。

[code]

    0
    0
    1
    2
    3
    *** stack smashing detected ***: <unknown> terminated
    Aborted (core dumped)
    
[/code]


CC BY-SA 4.0
2021-11-15T04:42:50.527
83629
2021-11-15T21:02:39.650
2021-11-15T21:02:39.650
4236
48756
question
c
c言語の配列コピーの未定義動作


提示コードに関しては立派な未定義動作を引き起こしています。

  * `buf[5]` に書き込んでいる
  * 標準組み込み関数 `memcpy` と同名の関数を自分で定義している

専門用語「未定義の動作」に関しては例えば [C :
配列の添字について](https://ja.stackoverflow.com/questions/15206/)
参照。よって未定義動作をするプログラムはあなたの勝手な期待通りに動くとは限りません。実際 Visual Studio 2019 Version
16.11.6 の [c++] x86 Debug Build では `0 0 0 0 0` 表示となってデバッガに `Run-Time Check
Failure #2 - Stack around the variable 'buf' was corrupted.`
となりました。事後にメモリ破壊が検出されたということのようです。

> 適切な未定義動作の例になっているのか自分でもよくわかりません

未定義動作は不適切なプログラムが起こすものなので「適切な未定義動作」なんてものはないです。最近の賢いコンパイラなら

[code]

    int main() {
        char buf[5];
        buf[5]='\0';
    }
    
[/code]

だけでも十分エラー検出してくれます。が、昔ながらの組み込み系コンパイラだとこの辺はコンパイル時にも実行時にも何の検出も行わずにただメモリ破壊を行うのみだったりします（上記コードはスタック上の未使用領域を壊すだけで無害だったりするので、検出が困難でたちが悪いっス。


CC BY-SA 4.0
2021-11-15T08:00:48.567
83639
2021-11-15T08:00:48.567
8589
83629
answer