質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

1170閲覧

c言語でstrcpy,strncpyを自作している最中のエラー

mamukura

総合スコア4

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2023/03/09 16:08

編集2023/03/09 17:00

実現したいこと

書いたコードがなぜエラーとなるのか理解する

前提

c言語のstrcpy関数、strncpy関数を自分で作っています。
しかし、その最中でエラーが起こってしまいました。
何が原因か見当がつかないため質問しています。

発生している問題・エラーメッセージ

文字列にs1何かエラーが生じている。

Run-Time Check Failure #2 - Stack around the variable 's1' was corrupted.

該当のソースコード

C

1ソースコード#include <stdio.h> 2 3char* strcpy(char* s1, const char* s2) { 4 char* t = s1; 5 while (*s1++ = *s2++); 6 return t; 7} 8 9 10char* strncpy(char* d, const char* s, size_t n) { 11 12 char* t = d; 13 int i = 0; 14 while (*d++ = *s++) { 15 i++; 16 if (i==n) 17 break; 18 } 19 i++; 20 for (; i < n; i++) 21 d[i] = '\0'; 22 23 return t; 24} 25 26int main(void) { 27 28 char s1[10]; 29 char* x = "XXXXXXXXX"; 30 31 strcpy(s1, x); strncpy(s1, "12345", 3); printf("s1=\"%s\"\n", s1); 32 strcpy(s1, x); strncpy(s1, "12345", 5); printf("s1=\"%s\"\n", s1); 33 strcpy(s1, x); strncpy(s1, "12345", 7); printf("s1=\"%s\"\n", s1); 34 return 0; 35}

試したこと

デバック無しで動作させた場合、やりたいこと自体はできているようでした。

補足情報(FW/ツールのバージョンなど)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazuma-s

2023/03/09 16:39

```Run-Time Check Failure #2 - Stack around the variable 's1' was corrupted. ではなく Run-Time Check Failure #2 - Stack around the variable 's1' was corrupted. ``` と書いてください。 ```c言語 ソースコード#include <stdio.h> ではなく、 ```C #include <stdio.h> と書いてください。
mamukura

2023/03/09 16:48

ご指摘ありがとうございます。 使い始めたばかりでフォーマットが分かっていませんでした。 回答者さんが見やすいように気を付けます。
kazuma-s

2023/03/09 16:52

気を付けるのなら、今すぐ質問を修正してください。
mamukura

2023/03/09 17:00

修正しました。
guest

回答2

0

ベストアンサー

d[i] = '\0'; で s1[10]以降に '\0' を入れています。
やいたいことは *d++ = '\0'; ではありませんか?

追記
変数の変化をちゃんと見ましょう。

strncpy(s1, "12345", 7); で呼び出したとき、
d は s1[0] を指しています。
whileループが終了した時点で、
s1[0] = '1'、s1[1] = '2'、...、s1[5] = '\0' で、
i は 5 ですが、i++; で i は 6 になります。
d は s1[6] を指しています。
forループで、d[i] は s1[12] です。
そこに '\0' を入れることで、配列の範囲外の領域を破壊します。

追記2
strncpy は、このようにも書けます。

C

1char *strncpy(char *d, const char *s, size_t n) 2{ 3 for (size_t i = 0; i < n; i++) 4 if (d[i] = *s) s++; 5 return d; 6}

投稿2023/03/09 16:32

編集2023/03/10 03:12
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mamukura

2023/03/09 16:37

回答ありがとうございます。 引数として渡している値は10未満のはずですが、iが10を超えてしまっているのですかね?
mamukura

2023/03/10 02:39

追記ありがとうございます。 非常に丁寧でよく理解できました。 また、このサイトでのマナーが分かっておらずご迷惑おかけしました。すみません。 みなさんの指摘を受けて修正していきます。 初歩的な質問ばかりになるとは思いますが今後も回答していただけると嬉しいです。
mamukura

2023/03/10 06:17

追記ありがとうございます。 0以外でインクリメントするようにすれば0を複製することができるのですね。ここまでシンプルに作れるとは驚きです。 ありがとうございます。
guest

0

d++してポインタから先頭要素がずれているのにd[i]としているためd[10]以上になってしまっていた。

投稿2023/03/09 16:47

mamukura

総合スコア4

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

int32_t

2023/03/09 22:05

kazuma-sさんの回答が少しでも役に立ったのなら、自己解決ではなくkazuma-sさんの回答をベストアンサーにすべきと思います。
mamukura

2023/03/10 00:26

ご指摘ありがとうございます。 ベストアンサー変更しておきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問