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

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

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

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

Q&A

解決済

2回答

6455閲覧

C++でmap型の変数をグローバル変数として初期化したいです。

KOTTON

総合スコア47

C++

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

0グッド

0クリップ

投稿2020/10/18 14:08

編集2020/10/18 15:28

環境

C++ 17
Clion
Cmake 3.16

問題のコード

以下のコードを実行するとエラーが起きます。
~~また、glovalVの初期化の段階でInitialization of 'globalV' with static storage duration may throw an exception that cannot be caughtという警告が出ます。
この変数をexternで他のファイルからアクセスしたいのでどうしてもグローバル変数にしたいのですがどうしたらいいですか?
intなどはグローバル変数にできるのにmapができない具体的な原因は何なんでしょう? ~~

どうやらこれはグローバル変数が問題なのではないみたいです。
globalVをmain関数の中に移動させてもクラッシュします。(終了コード3)

cpp

1#include <iostream> 2#include <map> 3 4std::map<const char*, bool> globalV = { 5 {"val", true} 6}; 7 8int main() { 9 std::cout << globalV.at("val") << std::endl; 10}

一応解決?

mapの中身を<const char*, bool> から <std::string, bool> に変更したところ一応動くようにはなりました。

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

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

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

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

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

SHOMI

2020/10/18 14:46 編集

警告なら出来ているのでは?
KOTTON

2020/10/18 14:51

プログラムがクラッシュします。 一応警告ではあるんですが実際にクラッシュが起こります。
SHOMI

2020/10/19 08:32 編集

クラッシュするコードをはって下さい。 質問にかかれているコードでは問題が再現しません。 →キーの型がポインタになっているのを見逃していました。SaitoAtsushiさんの回答をご参照下さい。
KOTTON

2020/10/18 14:58

僕の環境ではこのコードをそのまま張り付けて実行するとクラッシュします。今確認しました。 上に環境貼っておきます
SHOMI

2020/10/18 15:12 編集

今Clionで試してみましたが問題なく実行できましたよ。 Cleanしてビルドし直してみては?
KOTTON

2020/10/18 15:14

確かに今Visual Studioで実行したら普通に実行できました。 なんでこんなことが起こり得るんでしょうね、
KOTTON

2020/10/18 15:18

今気づいたんですがこれglobalVをローカルに移してもクラッシュします また、終了コード3で終了しました と出てます。 終了コード3はERROR_PATH_NOT_FOUND 3 (0x3) The system cannot find the path specified.らしいですが...
SHOMI

2020/10/19 08:31 編集

(誤認していたため削除)
guest

回答2

0

ベストアンサー

std::mapat は対応する要素が存在しないときに out_of_range 例外を投げることになっています。

質問者の例では key の型がポインタなので「ポインタの比較」をした結果、 map を初期化しようとしたときの "val"at で探したときの "val" が異なると判断されて例外が投げられたのだと思われます。

同内容の文字列リテラルは同一にまとめられてしまうこともあるのでそのようなときには一致してしまう場合もあります。 例外が投げらるか、対応する value を返すかのいずれの可能性も規格内で有りえます。

投稿2020/10/19 08:10

SaitoAtsushi

総合スコア5446

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

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

SHOMI

2020/10/19 08:26

あ、無意識にstringと思い込んで見逃していました。そのとおりですね。
KOTTON

2020/10/19 08:42

ちゃんと理解できている自信があまりないのですが、つまりこの場合文字列で検索されているのではなく、keyの中の"val"のアドレスとat()の中の"val"のアドレスが違うから範囲外と言われているってことですか?
SaitoAtsushi

2020/10/19 08:51

はい。 その理解で良いです。
KOTTON

2020/10/19 16:53

正確な回答ありがとうございます。納得しました。
guest

0

警告なら出来ているのでは?
初期化時にキャッチできない例外が発生する可能性があると言っています。


キーの型がポインタになっているのを見逃していました。
SaitoAtsushiさんの回答をご参照下さい。

投稿2020/10/18 14:50

編集2020/10/19 08:30
SHOMI

総合スコア4079

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

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

KOTTON

2020/10/19 16:53

SHOMIさんもありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問