teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

rubato6809さんのコメントを参考に書き換え

2019/11/17 06:03

投稿

raccy
raccy

スコア21778

answer CHANGED
@@ -7,6 +7,26 @@
7
7
  #include <string.h>
8
8
  #include <stdint.h>
9
9
 
10
+ // assert用
11
+ // テスト時はこのままにし、本番ではコメントアウトを外す
12
+ // #defien NDEBUG
13
+ #include <assert.h>
14
+
15
+ // 本来はヘッダ部分を分離して、それ読み込むが、
16
+ // 今回はmainの方に直接書いてあるため、個々に書く。
17
+ // mainと同じファイルに書く場合はこの部分は不要
18
+ #define SLEN 126
19
+
20
+ /**
21
+ * 受け取った文字列を二回表示にして返す。
22
+ * 引数は`SLEN`文字以下のnull終端文字列で無ければならない。
23
+ * そうで無い場合の動作は未定義とする。(何が起こるかは不明)
24
+ * この関数呼び出し時は、プログラム実行時は十分なメモリが存在し、
25
+ * malloc等の処理が失敗しない状態で無ければならない。
26
+ * メモリが不十分で、malloc等が失敗する場合の動作は未定義とする。
27
+ * これらの条件をつけた経緯はrubato6809さんのコメントを参考にすること。
28
+ */
29
+
10
30
  // ループ変数を除き一文字のみの変数名や引き数名は避ける。
11
31
  char *strdouble(char str[]) { // ) {の間はスペースを入れる。
12
32
  // ローカル変数は必要になったときに宣言する。
@@ -18,9 +38,12 @@
18
38
 
19
39
  // 確保するメモリはlenの2倍に1足した数だが、その値がSIZE_MAXを越える場合、
20
40
  // その計算がオーバーフロー起こす可能性がある。
41
+ // 受け取る引数の文字列の長さに制限が無い場合は、
21
- // そのため、あらかじめSIZE_MAXを越えないかを確認しておく
42
+ // あらかじめSIZE_MAXを越えないかを確認しておく
43
+ // しかし今回は、SLENによってサイズの最大サイズが固定であるため、
44
+ // SLENによって条件を満たさない場合があるかの確認をテスト時のみ行う。
22
- // 越えていたら、今回NULLを返す
45
+ // NDEBUGが有効の場合下記はコンパイル時に除外される
23
- if (len > (SIZE_MAX - 1) / 2) return NULL;
46
+ assert(SERN <= (SIZE_MAX - 1) / 2)
24
47
 
25
48
  // strの長さ(len)の2倍に1足した大きさの文字配列を割り当てる
26
49
  // null終端文字列は終端null文字分のために、文字列の長さに+1だけ大きさが必要。
@@ -29,9 +52,12 @@
29
52
  // sizeof(char)は例外なく必ず1である。charの場合は書かない。
30
53
  char *double_str = (char *)malloc(len * 2 + 1);
31
54
 
55
+ // メモリが十分に確保されていることが保証できなければ、
32
- // mallocしたら必ず戻り値がNULLでないかを確認する。
56
+ // mallocしたら必ず戻り値がNULLでないかを確認する必要がある
33
- // NULLの場合は適切なエラー処理をする今回は処理を中断してNULLを返すている。
57
+ // しかし、rubato6809さん曰く「まずエラーになりませんなっている。
58
+ // SLENのサイズが小さくても、空きメモリが極めて少ない状態でプログラムを
34
- if (double_str == NULL) return NULL;
59
+ // 実行した等の特殊な状況においては、失敗する恐れがあるが、
60
+ // 今回は、そのような場合は動作未定義として、チェックはしないこととする。
35
61
 
36
62
  // for文等でちまちまと代入せずにmemcpy()を使う。
37
63
  // 実装にもよるがmemcpy()はある程度のバイト列ごとにまとめてコピーするため、

2

誤字の修正

2019/11/17 06:02

投稿

raccy
raccy

スコア21778

answer CHANGED
@@ -40,7 +40,7 @@
40
40
  memcpy(double_str, str, len);
41
41
 
42
42
  // lenだけズレた位置にもう一度コピーする。
43
- // 終端null文字も含めるために、lenに1だけ確か数分コピーする。
43
+ // 終端null文字も含めるために、lenに+1したコピーする。
44
44
  memcpy(double_str + len, str, len + 1);
45
45
 
46
46
  // あとはdouble_strを返すだけ、お疲れ様でした。

1

思い処理・・・何かの思い出が詰まっているのだろうか…

2019/11/16 10:23

投稿

raccy
raccy

スコア21778

answer CHANGED
@@ -12,7 +12,7 @@
12
12
  // ローカル変数は必要になったときに宣言する。
13
13
  // 関数の先頭でまとめて宣言しない。
14
14
 
15
- // strlen()はい処理のため、呼び出しは一回のみにするように変数に入れる。
15
+ // strlen()はい処理のため、呼び出しは一回のみにするように変数に入れる。
16
16
  // strlen()の戻り値はsize_t型。
17
17
  size_t len = strlen(str);
18
18