質問編集履歴
7
title
CHANGED
File without changes
|
body
CHANGED
@@ -18,7 +18,7 @@
|
|
18
18
|
a[1]='s'
|
19
19
|
とメイン関数内に1バイト(8ビッド)ずつ格納されている。ここでchar型のバイト数が1バイトのため、例えばa[0]のアドレスが0019FF53とするとき、
|
20
20
|
a[1]のアドレスが0019FF54である。一バイトの差のため+1されている。また、逆のパターンのー1になることもある。
|
21
|
-
そこで、char* c =a;文字列データ "
|
21
|
+
そこで、char* c =a;文字列データ "ss"はメモリに格納される。そのときに文字列データ "ss"が格納されているメモリの先頭のアドレスがポインタ変数cに格納されるようになる。つまり、char *cは初期化されるようになる
|
22
22
|
string_duplicate(c)を用いて、変数aが変数cに代入されるときに、変数aのメモリのデータが変数cの文字列データに格納されるということ。
|
23
23
|
当然のことながら、変数aのメモリと変数cのメモリが独立した場所にあるということが分かる。
|
24
24
|
このことに気づかずになんとなくで書いてしまったこともミスの一つである。
|
6
title
CHANGED
File without changes
|
body
CHANGED
@@ -20,7 +20,7 @@
|
|
20
20
|
a[1]のアドレスが0019FF54である。一バイトの差のため+1されている。また、逆のパターンのー1になることもある。
|
21
21
|
そこで、char* c =a;文字列データ "abc"はメモリに格納される。そのときに文字列データ "ss"が格納されているメモリの先頭のアドレスがポインタ変数cに格納されるようになる。つまり、char *cは初期化されるようになる
|
22
22
|
string_duplicate(c)を用いて、変数aが変数cに代入されるときに、変数aのメモリのデータが変数cの文字列データに格納されるということ。
|
23
|
-
|
23
|
+
当然のことながら、変数aのメモリと変数cのメモリが独立した場所にあるということが分かる。
|
24
24
|
このことに気づかずになんとなくで書いてしまったこともミスの一つである。
|
25
25
|
|
26
26
|
|
5
title
CHANGED
File without changes
|
body
CHANGED
@@ -92,4 +92,4 @@
|
|
92
92
|
```
|
93
93
|
ここでepistemeさんとほぼ同じでchar *result =cとreturn resultを除いたこと以外はすべて同じです。関数もポインタの値を返すためにchar *型の関数にしました。
|
94
94
|
なぜ、関数内に新たなポインタ変数が必要なのでしょうか。ここではresultの事を指しています。コンパイルは通りますが例外が起こり実行できない状態となっております。新たに生成されたchar型の領域を
|
95
|
-
仮引数の値aをそのまま代入しましたが、returnで値を返すことができないのでしょうか?ポインタ変数が必要な理由を教えてください。
|
95
|
+
仮引数の値aをそのまま代入しましたが、returnでポインタ変数cの値をそのまま返すことができないのでしょうか?新たなポインタ変数が必要な理由を教えてください。
|
4
title
CHANGED
File without changes
|
body
CHANGED
@@ -91,5 +91,5 @@
|
|
91
91
|
|
92
92
|
```
|
93
93
|
ここでepistemeさんとほぼ同じでchar *result =cとreturn resultを除いたこと以外はすべて同じです。関数もポインタの値を返すためにchar *型の関数にしました。
|
94
|
-
なぜ、関数内に新たなポインタ変数が必要なのでしょうかコンパイルは通りますが例外が起こり実行できない状態となっております。新たに生成されたchar型の領域を
|
94
|
+
なぜ、関数内に新たなポインタ変数が必要なのでしょうか。ここではresultの事を指しています。コンパイルは通りますが例外が起こり実行できない状態となっております。新たに生成されたchar型の領域を
|
95
95
|
仮引数の値aをそのまま代入しましたが、returnで値を返すことができないのでしょうか?ポインタ変数が必要な理由を教えてください。
|
3
コードの改善点を書きたかったから
title
CHANGED
File without changes
|
body
CHANGED
@@ -1,5 +1,33 @@
|
|
1
|
+
すいません。たくさんのご指摘ありがとうございます。
|
2
|
+
ご指摘と反省点、また基本となる知識も踏まえたうえで最後に疑問を書かせていただきます。最初の方は自分の反省なので基本無視して大丈夫です。疑問の場所はコードの下です。もし間違いがありましたらご指摘をお願いします。
|
3
|
+
|
4
|
+
ポインタで関数の値を返すはずがvoid型となっているため、値が返されない。
|
5
|
+
つまり、参照返しができていないということが問題
|
6
|
+
string_duplicate関数でポインタ型変数char *aのメモリ内にあるデータが、
|
7
|
+
引数として関数に渡されているにも関わらず、関数内の文字列cがそのままアドレスaに代入されてしまって、10バイトの文字列データが使われない状態となっている。
|
8
|
+
その理由がwhile ( *a!= '\0') 内にあるc = a;がアドレスを代入していることが原因。値を代入するには*c=*aをする必要がある。
|
9
|
+
|
10
|
+
ここで混同してしまったのが配列において、aが配列のポインタ変数となっている。
|
11
|
+
そのため*を付けるつけないの意味合いが全く異なってしまうことになる。*有りは配列のデータにある値を代入する。
|
12
|
+
またchar型の領域を確保したがfree関数を使わずに値を解放せずにしている。つまりいらなくなったaの配列のデータを消去せずにいる。
|
13
|
+
自分で気づかなかったことが、メイン関数に確保されているchara[10]のメモリと
|
14
|
+
string_duplicateのchar *aのメモリの場所が全く異なった場所にある。
|
15
|
+
細かく書くと、
|
16
|
+
このプログラムだとメイン関数内にあるchar a[10]="ss"は
|
1
|
-
|
17
|
+
a[0]='s'
|
18
|
+
a[1]='s'
|
19
|
+
とメイン関数内に1バイト(8ビッド)ずつ格納されている。ここでchar型のバイト数が1バイトのため、例えばa[0]のアドレスが0019FF53とするとき、
|
20
|
+
a[1]のアドレスが0019FF54である。一バイトの差のため+1されている。また、逆のパターンのー1になることもある。
|
2
|
-
|
21
|
+
そこで、char* c =a;文字列データ "abc"はメモリに格納される。そのときに文字列データ "ss"が格納されているメモリの先頭のアドレスがポインタ変数cに格納されるようになる。つまり、char *cは初期化されるようになる
|
22
|
+
string_duplicate(c)を用いて、変数aが変数cに代入されるときに、変数aのメモリのデータが変数cの文字列データに格納されるということ。
|
23
|
+
つまり、当然のことながら、変数aのメモリと変数cのメモリが独立した場所にあるということが分かる。
|
24
|
+
このことに気づかずになんとなくで書いてしまったこともミスの一つである。
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
|
3
31
|
```ここに言語を入力
|
4
32
|
#define _CRT_SECURE_NO_WARNINGS
|
5
33
|
#include <stdio.h>
|
@@ -32,9 +60,36 @@
|
|
32
60
|
|
33
61
|
}
|
34
62
|
```
|
35
|
-
|
63
|
+
|
36
|
-
この
|
64
|
+
そこで、今までの反省を含めた結果のコードです
|
65
|
+
```#define _CRT_SECURE_NO_WARNINGS
|
66
|
+
#include <stdio.h>
|
67
|
+
#include <stdlib.h>
|
68
|
+
|
69
|
+
char* string_duplicate( char* a) {
|
70
|
+
|
71
|
+
char* c;
|
37
|
-
|
72
|
+
c = (char*)malloc(sizeof(char) * 10);
|
73
|
+
|
38
|
-
while
|
74
|
+
while (*a != '\0') {
|
75
|
+
*c = *a;
|
76
|
+
c++;
|
77
|
+
a++;
|
78
|
+
}
|
79
|
+
*c = '\0';
|
80
|
+
|
81
|
+
return c;
|
82
|
+
}
|
83
|
+
|
84
|
+
int main() {
|
85
|
+
char a[10] = "ss";
|
86
|
+
char* c = string_duplicate(a);
|
87
|
+
printf("%s\n", c);
|
88
|
+
free(c);
|
89
|
+
return 0;
|
90
|
+
}
|
91
|
+
|
92
|
+
```
|
39
|
-
*を
|
93
|
+
ここでepistemeさんとほぼ同じでchar *result =cとreturn resultを除いたこと以外はすべて同じです。関数もポインタの値を返すためにchar *型の関数にしました。
|
94
|
+
なぜ、関数内に新たなポインタ変数が必要なのでしょうかコンパイルは通りますが例外が起こり実行できない状態となっております。新たに生成されたchar型の領域を
|
40
|
-
|
95
|
+
仮引数の値aをそのまま代入しましたが、returnで値を返すことができないのでしょうか?ポインタ変数が必要な理由を教えてください。
|
2
プログラムの変更
title
CHANGED
@@ -1,1 +1,1 @@
|
|
1
|
-
mallocを使って新しい配列に文字列をコピー
|
1
|
+
mallocを使って新しい配列に文字列をコピーしたい
|
body
CHANGED
@@ -33,7 +33,8 @@
|
|
33
33
|
}
|
34
34
|
```
|
35
35
|
main関数内で適当に文字列ssと入力しstring_duplicate関数を用いて新しくできた大きさ10の配列を用意し、コピーして出力させるという内容です。
|
36
|
+
この方はコードができている方です。
|
36
|
-
|
37
|
+
前回はwhile文内にある*c=*aとアドレス内にある文字列を代入しましたが、別の文字が表示されるようになりました。そのまま、アドレス内の値が代入されたのになぜそのようになってしまったのでしょうか?
|
37
38
|
while文内で*を入れると入れないの差は何ですか?
|
38
39
|
*を消した場合にはすべて正常にコピーされましたが、その場合はprintf("%s", c);をmain関数にあるstring_duplicate(c);の後に書いたらできるようになりましたが、while文を抜け出した直後printf("%s", c);を入れると値がsssと一つ追加された状態となってしまいました。
|
39
40
|
ここもどのように動いてるのかが分からないです。*a!= '\0'の条件でsが追加される理由を教えてほしいです.
|
1
プログラムの変更
title
CHANGED
File without changes
|
body
CHANGED
@@ -1,21 +1,23 @@
|
|
1
1
|
c言語のmallocについて質問です。
|
2
2
|
mallocはその引数として確保すべきメモリ領域の大きさ (バイト数) を渡すと, 領域が確保され, その先頭番地が返される.ということが分かりましたが、実際に与えられた文字列の許容範囲内に格納されるとどうなるのかという検証をしました。
|
3
3
|
```ここに言語を入力
|
4
|
-
define _CRT_SECURE_NO_WARNINGS
|
4
|
+
#define _CRT_SECURE_NO_WARNINGS
|
5
5
|
#include <stdio.h>
|
6
6
|
#include <stdlib.h>
|
7
7
|
void string_duplicate(char *a) {
|
8
8
|
int i = 0;
|
9
9
|
char* c;
|
10
|
-
c = (char*)malloc(sizeof(char)
|
10
|
+
c = (char*)malloc(sizeof(char)*10 );
|
11
11
|
|
12
12
|
while ( *a!= '\0') {
|
13
|
-
|
13
|
+
c = a;
|
14
|
-
|
14
|
+
c++;
|
15
15
|
a++;
|
16
16
|
|
17
17
|
}
|
18
|
-
|
18
|
+
|
19
|
+
|
20
|
+
|
19
21
|
}
|
20
22
|
void main() {
|
21
23
|
char a[10] = "ss";
|
@@ -25,8 +27,9 @@
|
|
25
27
|
printf("%s\n", c);
|
26
28
|
|
27
29
|
string_duplicate(c);
|
30
|
+
printf("%s", c);
|
31
|
+
|
28
32
|
|
29
|
-
|
30
33
|
}
|
31
34
|
```
|
32
35
|
main関数内で適当に文字列ssと入力しstring_duplicate関数を用いて新しくできた大きさ10の配列を用意し、コピーして出力させるという内容です。
|