質問編集履歴

7

2020/05/26 13:55

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -38,7 +38,7 @@
38
38
 
39
39
  a[1]のアドレスが0019FF54である。一バイトの差のため+1されている。また、逆のパターンのー1になることもある。
40
40
 
41
- そこで、char* c =a;文字列データ "abc"はメモリに格納される。そのときに文字列データ "ss"が格納されているメモリの先頭のアドレスがポインタ変数cに格納されるようになる。つまり、char *cは初期化されるようになる
41
+ そこで、char* c =a;文字列データ "ss"はメモリに格納される。そのときに文字列データ "ss"が格納されているメモリの先頭のアドレスがポインタ変数cに格納されるようになる。つまり、char *cは初期化されるようになる
42
42
 
43
43
  string_duplicate(c)を用いて、変数aが変数cに代入されるときに、変数aのメモリのデータが変数cの文字列データに格納されるということ。
44
44
 

6

2020/05/26 13:55

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -42,7 +42,7 @@
42
42
 
43
43
  string_duplicate(c)を用いて、変数aが変数cに代入されるときに、変数aのメモリのデータが変数cの文字列データに格納されるということ。
44
44
 
45
- つまり、当然のことながら、変数aのメモリと変数cのメモリが独立した場所にあるということが分かる。
45
+ 当然のことながら、変数aのメモリと変数cのメモリが独立した場所にあるということが分かる。
46
46
 
47
47
  このことに気づかずになんとなくで書いてしまったこともミスの一つである。
48
48
 

5

2020/05/26 12:42

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -186,4 +186,4 @@
186
186
 
187
187
  なぜ、関数内に新たなポインタ変数が必要なのでしょうか。ここではresultの事を指しています。コンパイルは通りますが例外が起こり実行できない状態となっております。新たに生成されたchar型の領域を
188
188
 
189
- 仮引数の値aをそのまま代入しましたが、returnで値を返すことができないのでしょうか?ポインタ変数が必要な理由を教えてください。
189
+ 仮引数の値aをそのまま代入しましたが、returnでポインタ変数cの値をそのまま返すことができないのでしょうか?新たなポインタ変数が必要な理由を教えてください。

4

2020/05/26 12:41

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -184,6 +184,6 @@
184
184
 
185
185
  ここでepistemeさんとほぼ同じでchar *result =cとreturn resultを除いたこと以外はすべて同じです。関数もポインタの値を返すためにchar *型の関数にしました。
186
186
 
187
- なぜ、関数内に新たなポインタ変数が必要なのでしょうかコンパイルは通りますが例外が起こり実行できない状態となっております。新たに生成されたchar型の領域を
187
+ なぜ、関数内に新たなポインタ変数が必要なのでしょうか。ここではresultの事を指しています。コンパイルは通りますが例外が起こり実行できない状態となっております。新たに生成されたchar型の領域を
188
188
 
189
189
  仮引数の値aをそのまま代入しましたが、returnで値を返すことができないのでしょうか?ポインタ変数が必要な理由を教えてください。

3

コードの改善点を書きたかったから

2020/05/26 12:39

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -1,6 +1,62 @@
1
- c言語mallocにつて質問です。
1
+ すいません。たくさんご指摘ありがとうござす。
2
2
 
3
+ ご指摘と反省点、また基本となる知識も踏まえたうえで最後に疑問を書かせていただきます。最初の方は自分の反省なので基本無視して大丈夫です。疑問の場所はコードの下です。もし間違いがありましたらご指摘をお願いします。
4
+
5
+
6
+
7
+ ポインタで関数の値を返すはずがvoid型となっているため、値が返されない。
8
+
9
+ つまり、参照返しができていないということが問題
10
+
11
+ string_duplicate関数でポインタ型変数char *aのメモリ内にあるデータが、
12
+
13
+ 引数として関数に渡されているにも関わらず、関数内の文字列cがそのままアドレスaに代入されてしまって、10バイトの文字列データが使われない状態となっている。
14
+
15
+ その理由がwhile ( *a!= '\0') 内にあるc = a;がアドレスを代入していることが原因。値を代入するには*c=*aをする必要がある。
16
+
17
+
18
+
19
+ ここで混同してしまったのが配列において、aが配列のポインタ変数となっている。
20
+
21
+ そのため*を付けるつけないの意味合いが全く異なってしまうことになる。*有りは配列のデータにある値を代入する。
22
+
23
+ またchar型の領域を確保したがfree関数を使わずに値を解放せずにしている。つまりいらなくなったaの配列のデータを消去せずにいる。
24
+
25
+ 自分で気づかなかったことが、メイン関数に確保されているchara[10]のメモリと
26
+
27
+ string_duplicateのchar *aのメモリの場所が全く異なった場所にある。
28
+
29
+ 細かく書くと、
30
+
31
+ このプログラムだとメイン関数内にあるchar a[10]="ss"は
32
+
33
+ a[0]='s'
34
+
35
+ a[1]='s'
36
+
37
+ とメイン関数内に1バイト(8ビッド)ずつ格納されている。ここでchar型のバイト数が1バイトのため、例えばa[0]のアドレスが0019FF53とするとき、
38
+
39
+ a[1]のアドレスが0019FF54である。一バイトの差のため+1されている。また、逆のパターンのー1になることもある。
40
+
3
- mallocはその引数として確保すべきメモリ領域 (バイト数) を渡すと, 領域確保され, その先頭番地される.といことが分かましたが実際に与えられた文字列の許容範囲内に格納されるとどうなるのかという検証をしました。
41
+ そこで、char* c =a;文字列データ "abc"はメモリに格納される。そに文字列データ "ss"格納されているメモリの先頭のアドレスポインタ変数cに格納されるになる。つまり、char *cは初期化されるなる
42
+
43
+ string_duplicate(c)を用いて、変数aが変数cに代入されるときに、変数aのメモリのデータが変数cの文字列データに格納されるということ。
44
+
45
+ つまり、当然のことながら、変数aのメモリと変数cのメモリが独立した場所にあるということが分かる。
46
+
47
+ このことに気づかずになんとなくで書いてしまったこともミスの一つである。
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+
57
+
58
+
59
+
4
60
 
5
61
  ```ここに言語を入力
6
62
 
@@ -66,14 +122,68 @@
66
122
 
67
123
  ```
68
124
 
69
- main関数内で適当に文字列ssと入力しstring_duplicate関数を用いて新しくできた大きさ10の配列を用意し、コピーして出力させるという内容です。
70
125
 
71
- この方はコードができている方です。
72
126
 
73
- 前回はwhile文内にある*c=*aとアドレス内にある文字列を代入ししたが、別文字が表示されるようになりまし。そまま、アレス内の値が代入されたのになぜそのようになってしまったのしょうか? 
127
+ そこで、今反省を含め結果コードで
74
128
 
75
- while文内で*を入れると入れないの差は何ですか?
129
+ ```#define _CRT_SECURE_NO_WARNINGS
76
130
 
77
- *を消した場合にはすべて正常にコピーされましたが、その場合はprintf("%s", c);をmain関数にあるstring_duplicate(c);の後に書いたらできるようになりましたが、while文を抜け出した直後printf("%s", c);を入れると値がsssと一つ追加された状態となってしまいました。
131
+ #include <stdio.h>
78
132
 
133
+ #include <stdlib.h>
134
+
135
+
136
+
137
+ char* string_duplicate( char* a) {
138
+
139
+
140
+
141
+ char* c;
142
+
143
+ c = (char*)malloc(sizeof(char) * 10);
144
+
145
+
146
+
147
+ while (*a != '\0') {
148
+
149
+ *c = *a;
150
+
151
+ c++;
152
+
153
+ a++;
154
+
155
+ }
156
+
157
+ *c = '\0';
158
+
159
+
160
+
161
+ return c;
162
+
163
+ }
164
+
165
+
166
+
167
+ int main() {
168
+
169
+ char a[10] = "ss";
170
+
171
+ char* c = string_duplicate(a);
172
+
173
+ printf("%s\n", c);
174
+
175
+ free(c);
176
+
177
+ return 0;
178
+
179
+ }
180
+
181
+
182
+
183
+ ```
184
+
185
+ ここでepistemeさんとほぼ同じでchar *result =cとreturn resultを除いたこと以外はすべて同じです。関数もポインタの値を返すためにchar *型の関数にしました。
186
+
187
+ なぜ、関数内に新たなポインタ変数が必要なのでしょうかコンパイルは通りますが例外が起こり実行できない状態となっております。新たに生成されたchar型の領域を
188
+
79
- ここもどように動いてる分からないです。*a!= '\0'条件追加される理由を教えてほしです.
189
+ 仮引数値aをそまま代入しました、returnで値を返すことができないのでしょうか?ポインタ変数必要な理由を教えてくださ

2

プログラムの変更

2020/05/26 11:43

投稿

退会済みユーザー
test CHANGED
@@ -1 +1 @@
1
- mallocを使って新しい配列に文字列をコピーする
1
+ mallocを使って新しい配列に文字列をコピーしたい
test CHANGED
@@ -68,7 +68,9 @@
68
68
 
69
69
  main関数内で適当に文字列ssと入力しstring_duplicate関数を用いて新しくできた大きさ10の配列を用意し、コピーして出力させるという内容です。
70
70
 
71
+ この方はコードができている方です。
72
+
71
- ここではwhile文内にある*c=*aとアドレス内にある文字列を代入しましたが、別の文字が表示されるようになりました。そのまま、アドレス内の値が代入されたのになぜそのようになってしまったのでしょうか? 
73
+ 前回はwhile文内にある*c=*aとアドレス内にある文字列を代入しましたが、別の文字が表示されるようになりました。そのまま、アドレス内の値が代入されたのになぜそのようになってしまったのでしょうか? 
72
74
 
73
75
  while文内で*を入れると入れないの差は何ですか?
74
76
 

1

プログラムの変更

2020/05/23 03:15

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  ```ここに言語を入力
6
6
 
7
- define _CRT_SECURE_NO_WARNINGS
7
+ #define _CRT_SECURE_NO_WARNINGS
8
8
 
9
9
  #include <stdio.h>
10
10
 
@@ -16,15 +16,15 @@
16
16
 
17
17
  char* c;
18
18
 
19
- c = (char*)malloc(sizeof(char) *10);
19
+ c = (char*)malloc(sizeof(char)*10 );
20
20
 
21
21
 
22
22
 
23
23
  while ( *a!= '\0') {
24
24
 
25
- *c = *a;
25
+ c = a;
26
26
 
27
-
27
+ c++;
28
28
 
29
29
  a++;
30
30
 
@@ -32,7 +32,11 @@
32
32
 
33
33
  }
34
34
 
35
- printf("%s", c);
35
+
36
+
37
+
38
+
39
+
36
40
 
37
41
  }
38
42
 
@@ -52,7 +56,9 @@
52
56
 
53
57
  string_duplicate(c);
54
58
 
55
-
59
+ printf("%s", c);
60
+
61
+
56
62
 
57
63
 
58
64