memset()後に、const char*がprintf()で表示できない?
- 評価
- クリップ 0
- VIEW 1,272
memmove()、memset()後のprintf()うまく動きません。
文字列"123456789"を'A'に変換するプログラムです。
①の部分をコメントアウトすると想定通り動き、str1とstr2(AAAAAAAAA)が表示されます。
①を追加すると、異常終了するようで何も表示されません。
memmove()、memset後にconst char* str1を操作してはいけないんでしょうか?
constであるstr1は書き換えていないつもりなんですが・・・。
原因をご教授願います。
根本的に間違っている点がありましたら指摘お願い致します。
const char* str1 = "123456789";
char str2[] = {0};
:
:
:
printf("%s\n", str1);
memmove(str2, str1, 9);
memset(str2, 'A', 9);
printf("%s\n", str2);
① printf("%s\n", str1);
:
:
:
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+1
こんにちは。
意外と思いますが、心臓に悪いプログラムですよ。
char str2[] = {0};
はstr2の領域としてchar型を1つだけ確保し、0で初期化する指示になってます。
つまり、str2は1バイトしか領域が確保されていません。そこに9バイトをコピーしてますので、残りの8バイトはstr2でない他のエリアを破壊しています。
そのような操作をすると、どのような結果になるのか未定義なのです。
char str2[9]={0};
とすれば9バイト確保されます。
なお、文字列は最後に0が付いてます。つまり、"123456789"は最後に0があるので全部で10バイトあります。
最後の0(NULL終端)の存在を忘れないように。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
str2
の領域が1バイトしか確保されていないのが原因です。
memmoveではコピー先の領域が確保されるわけではありません。
このようにしてみてください。
char str2[10] = {0};
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
char str2[] = {0};
となっていますが、これではstr2
の領域は1バイトしかありません。9バイト書き込めば、どこのメモリを書き潰すかわかりません。
あと、memcpy
やmemmove
では、ヌルバイトかどうかを関係なくコピーします。str1
は最後のヌル文字まで入れて10バイトありますが、9バイトだけコピーすると最後のヌル文字がない状態となります(これまた文字列として扱うとまずいです)。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.35%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2016/05/20 15:56
memcpyやmemmoveではmemmove(str2, str1, 10)としてヌル文字を考慮しますが、
memsetで変換を行う際は、memset(str2, 'A', 10)ではヌル文字も変換されてしまいますよね?
memset(str2, 'A', 9)を行った後、str2の末尾にヌル文字を入れれば良いでしょうか。
2016/05/20 16:27
その通りです。
しかし、文字列を扱う場合は、strcpy()系の文字列操作ライブラリを使うことが多いです。
2016/05/20 16:47