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

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

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

charは文字データ型を指します。一文字分の文字コードの格納を想定としている型です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

496閲覧

charの中身の表示が、空のfor文の有無に依って変わるのはなぜですか?

kamekawashinta

総合スコア39

char

charは文字データ型を指します。一文字分の文字コードの格納を想定としている型です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2017/11/21 07:08

編集2017/11/21 07:11

u16Stringをchar化する際、関数によって初期化していたのですが
初期化全文の前のfor文(中身は実行なし)の有無に依ってcoutの表示が変化してしまいます。
for文が存在する場合、期待した表示になります。(path//to//the//moon)が表示される。
空のfor文によって動作が変わる理由がよく分からず、困っています。
理由をご教授いただけると幸いです。

c++

1/* 2u16Stringをcharへ変換する関数 3*/ 4char* convertU16StrToChar(std::u16string& str) { 5 6 7 size_t strSize = str.length(); 8 mbstate_t state; 9 mbsinit(&state); 10 char buf[5]; 11 char out[32]; 12 size_t byteNum; 13 size_t outIndex = 0; 14 for (int i = 0; i < strSize; ++i) { 15 byteNum = c16rtomb(buf, str[i], &state); 16 for (size_t i = 0; i < byteNum; i++) 17 { 18 out[outIndex] = buf[i]; 19 outIndex++; 20 } 21 } 22 23 return out; 24} 25 26int main(){ 27std::u16string path = u"path//to//the//moon"; 28 29/*for (size_t i = 0; i < 1; i++) { 30 }ここをコメントアウトすると、☆部分でcharの中身が表示できる*/ 31 32 char* pathChar 33 = convertU16StrToChar(path); 34 35 for (size_t i = 0; i < 15; i++) { 36//☆ 37 cout << pathChar[i]; 38 39 } 40} 41 42コード

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

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

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

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

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

guest

回答2

0

こういう警告が出ているはずです。

warning: address of stack memory associated with local variable 'out' returned

out(が指しているメモリのデータ)の寿命はconvertU16StrToChar関数内だけなので、
戻り値として返してもそのうち消えてなくなる値です。

したがって、forがないとき、たまたま上書きされずに残っていて表示できているだけです。

投稿2017/11/21 07:42

ozwk

総合スコア13521

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

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

0

ベストアンサー

C++

1 char out[32]; 2 3 /* 中略 */ 4 5 return out;

ローカル変数は、関数を抜けた時点で解放されるので、そのまま返してしまえば未定義の動作となります(まさに今回のような、「無関係な部分の書き方によって動いたり動かなかったり」というようなことにもなります)。

対策としては、

  • staticな配列、大域変数など、ローカル変数以外のポインタを返す
  • std::stringなど、適当なオブジェクトの形で返す

などが考えられます。とりわけ、char out[32];となっていると、これをあふれるだけの文字列が来た場合にうまく処理できなくなりますので、可変長のオブジェクトを使うことをおすすめします。

投稿2017/11/21 07:39

maisumakun

総合スコア145183

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

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

kamekawashinta

2017/11/21 08:20

ご教授通り std::vector<char>を使って渡すことで解決することが出来ました。 変数の寿命等の理解を頑張ります。この度はありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問