ページ 11

質問です

Posted: 2010年3月18日(木) 11:43
by くりあ
前回は、ありがとうございました。
またboost::anyで分からないことが出てしまいました。
前回のを解決にしてしまったので新規に作りました。
すいません。

DXライブラリの
FileRead_open()
関数に、
boost::any
に入った文字列を渡したいのですが、エラーが出てしまいました。
FileRead_open(boost::any_cast<char>(aaa))
としてみたのですが、
DxLib::FileRead_open' : 1 番目の引数を 'char' から 'const char *' に変換できません。
とのことです。
どのようにしたら、正常に動いてくれるでしょうか?

Re:質問です

Posted: 2010年3月18日(木) 12:02
by fatens
boostは抜きにして、文字列は何型か理解していますか?
エラーメッセージの通りだと思いますが。

Re:質問です

Posted: 2010年3月18日(木) 12:09
by たかぎ
> boostは抜きにして、文字列は何型か理解していますか?

それもありますが、ポインタが指している文字列はすでに生存期間を終えている可能性がありますね。

Re:質問です

Posted: 2010年3月18日(木) 14:34
by くりあ
ポインタということですか?
charの部分を変えれば何とかなるのでしょうか?
変えたらメモリのアクセス違反か何かで警告が出ました。

Re:質問です

Posted: 2010年3月18日(木) 23:17
by Justy
>boost::any に入った文字列
 問題は anyに入った文字列の型です。
 何の型で入っていますか?
 どうやって代入しましたか?

>変えたらメモリのアクセス違反か何かで警告が出ました
 完全に情報が不足しています。
 何をどう変えたら、何のエラーが出たのですか?

Re:質問です

Posted: 2010年3月19日(金) 00:15
by くりあ
char aaa[500]に入っている文字列を関数からreturnで戻して、
=で直接代入しました。


boost::any_cast<char>(aaa)
の、          ↑のchar部分を、const char *にしてみたりしました。
すると、0x7679fbae でハンドルされていない例外が発生しました。と、警告が出てきました。


この他に足りない情報はありますでしょうか?

Re:質問です

Posted: 2010年3月19日(金) 00:31
by たかぎ
> char aaa[500]に入っている文字列を関数からreturnで戻して、
> =で直接代入しました。

予想通りのことが起きているような気がします。
いや、それ以上ですね。
この部分のコードを貼ってみてください。

Re:質問です

Posted: 2010年3月19日(金) 13:32
by くりあ
char* tesuto(){

aaa[500] = "";
std::string deeta;

std::ifstream ofs( "tesuto.txt" );

getline(ofs,deeta);

strcpy(aaa,deeta.c_str());

return a
}

main(){

boost::any a;

a = tesuto();

FileRead_open(boost::any_cast<char *>(a)) ;
 ・
 ・
 ・
}




こんな感じになっってると思います。
すいません。元がぐちゃぐちゃしてるので抜き出してみたのですが、
どこか変になってるかもしれません。

Re:質問です

Posted: 2010年3月19日(金) 14:09
by たかぎ
元の通りのものを貼ってもらわないと、どうしようもありません。

Re:質問です

Posted: 2010年3月19日(金) 16:29
by くりあ
すいません。 return a; じゃないですね。 return aaa;ですね。
間違えました。やっていることは変わらないと思います。
あと、少し違っているとすれば、boost::anyが構造体になっているくらいだと思うのですが……
非常に勝手なのは分かっていますが、これで何とかならないでしょうか?
質問には出来る限りお答えしますので、何とか……本当にすいません。

Re:質問です

Posted: 2010年3月19日(金) 17:05
by fatens
実際のコードを提示するのが解決への一番の近道だと思いますが……
とりあえず、以下のコードの問題点が分かりますか?

#include <stdio.h>

int *func(void)
{
int a = 10;
return &a;
}

int main(void)
{
int *p = func();
printf("%d", *p);
return 0;
}

Re:質問です

Posted: 2010年3月19日(金) 17:51
by たかぎ
結局は、以前に指摘したように...

ポインタが指している文字列はすでに生存期間を終えている。

ということです。

Re:質問です

Posted: 2010年3月19日(金) 21:27
by くりあ
引数にポインタを渡して、そこに書き込むようにしたらいいのでしょうか?

通常はこのような場合どのように処理するのが一般的なのでしょうか?

Re:質問です

Posted: 2010年3月20日(土) 00:17
by たかぎ
> 通常はこのような場合どのように処理するのが一般的なのでしょうか?

std::string型で返すのが普通です。
そして、boost::anyに代入するときも、std::string型のまま代入します。

ただ、tesuto関数に関して強い例外安全保障を目指すのであれば、std::auto_ptr<std::string>を返すとか、std::stringを参照やポインタで渡すなどの対策が必要になるかと思います。
tesutoの結果を常にboost::anyに代入するのであれば、最初からboost::anyで返す方がよいかもしれません。

Re:質問です

Posted: 2010年3月20日(土) 14:12
by くりあ
何度もお答えいただきありがとうございます。
また質問で申し訳ありませんが、
return型クラスにする場合は、どのように宣言したらよいのでしょう?

Re:質問です

Posted: 2010年3月20日(土) 14:14
by くりあ
fatensさんの回答に何もお答えしないで申し訳ありませんでした。
気が付かないうちに飛ばして読んでいてしまっていたようです。
本当に申し訳ありませんでした。

Re:質問です

Posted: 2010年3月20日(土) 15:51
by softya
とりあえず混乱しているようですから整理して見ましょう。
まず、問題が再現するコンパクトなソースコードを作って添付してみてください。
コンパクトにする場合、元の構造体やクラス?関数?の構造はできるだけ残してください。

前回のお話でC++的に作っているとの事でしたが、
http://www.play21.jp/board/formz.cgi?ac ... &rln=48867
char *型などメモリスコープをC言語的に管理なければいけないデータ型を使ってC++的なstd::string型を使わない理由を伺ってよろしいですか? 画像

Re:質問です

Posted: 2010年3月20日(土) 18:42
by fatens
>fatensさんの回答に何もお答えしないで申し訳ありませんでした。

いえ、とくに気にしてませんが、先のコードの問題点も把握しておくと良いとは思います。

Re:質問です

Posted: 2010年3月21日(日) 22:02
by くりあ
softyaさんのいっているソースコードを作ってコンパイルしたら、リンクの時他のライブラリと競合しています。などとエラー大量に出てきてしまってもう分かりません。自分はいったい何をしたんでしょうか……

しかも、作っていたら明らかにおかしいところもりましたし。
もう自分が何したいのか分からなくなってきました。
頭が付いていけません。自分が今、何が分からないのか分かりません。

ここまで来て、申し訳ありませんが、質問を変える、というか、自分の聞きたいことを整理します。
本当にすいません。

関数の戻り値にstd::ifstreamで開いたファイルから読み込んだ文字列を指定して、その文字を構造体の中のboost::anyに代入したいのです。最終的にこの文字列をDXライブラリのFileRead_open()関数に渡したいのです。
なぜ、boost::anyかというと、これをプログラム内で使いまわしたいからです。あと、boost::anyの使い方の勉強も兼ねています。この場合、どのようにするのがいいでしょうか?

大まかな流れ的にはどのような処理になるのでしょうか?

ということを聞きたいです。
本当に申し訳ありません。

Re:質問です

Posted: 2010年3月21日(日) 22:16
by softya
>関数の戻り値に std::ifstreamで開いたファイルから読み込んだ文字列を指定して、その文字を構造体の中のboost::anyに代入したいのです。最終的にこの文字列をDXライブラリのFileRead_open()関数に渡したいのです。
なぜ、boost::anyかというと、これをプログラム内で使いまわしたいからです。あと、boost::anyの使い方の勉強も兼ねています。この場合、どのようにするのがいいでしょうか?

その説明だけだとstd::string型じゃなくて、boost::anyじゃないとダメない理由がわかりませんね。
たしか数値も代入するという所からboost::anyになったはずですが?

それと、関数の戻り値にchar *型を使う場合はローカル変数のスコープやメモリの動的確保をちゃんと理解していない使えないことを理解してください。今まで提示されたコートはfatensさんのサンプルコードが提示している問題を理解出来ないと直せませんよ。

Re:質問です

Posted: 2010年3月22日(月) 00:27
by たかぎ
> 頭が付いていけません。自分が今、何が分からないのか分かりません。

本人が分からなければ、他人はもっとわかりませんし、ついてもいけません。
小手先のテクニックではなく、そもそも何をしたいのかをもう一度整理してください。

Re:質問です

Posted: 2010年3月25日(木) 00:42
by くりあ
とりあえず、頭を冷やしてきてたつもりです。

>fatensさんのサンプルコードが提示している問題を理解出来ないと直せませんよ。

関数内で利用したint aのメモリ領域は、関数が終了すると自動的に解放されてしまうため、その領域のアドレスを返しても、指している場所にはもうデータは残っていないために、正常に動かないから間違っている。と解釈したのですが合っていますでしょうか?



>その説明だけだとstd::string型じゃなくて、boost::anyじゃないとダメない理由がわかりませんね。
たしか数値も代入するという所からboost::anyになったはずですが?

FileRead_open()だけでなく、他の部分でも使う予定でいます。その中には数値も入る場所があるのでboost::anyを使いたいのです。言葉が足りず、申し訳ありません。




>本人が分からなければ、他人はもっとわかりませんし、ついてもいけません。
小手先のテクニックではなく、そもそも何をしたいのかをもう一度整理してください。

その通りですね。本当に申し訳あしません。自分では、イメージできているのと思ったのに、実際は全然出来ていなかったです。

Re:質問です

Posted: 2010年3月25日(木) 11:13
by softya
>関数内で利用したint aのメモリ領域は、関数が終了すると自動的に解放されてしまうため、その領域のアドレスを返しても、指している場所にはもうデータは残っていないために、正常に動かないから間違っている。と解釈したのですが合っていますでしょうか?

あっています。
だったら別の方法があるはずですよね。

>FileRead_open()だけでなく、他の部分でも使う予定でいます。その中には数値も入る場所があるのでboost::anyを使いたいのです。言葉が足りず、申し訳ありません。

私だったら型は、ポリモーフィズムでクラスに隠蔽しますね。boost::any_cast<>とかも表面に出てこなくなるので、扱いやすくなると思いますよ。とりあえず必要な型は、std::string型とint型だけですかね。
そう言えば、データと名前がセットになっているとか言ってませんでした?

Re:質問です

Posted: 2010年3月25日(木) 11:21
by たかぎ
以前の質問を前提にされても追跡しきれませんし、結局何がやりたいのかもよくわかりません。
疑問点を整理した上で、十分な情報を添えて再質問されることをお勧めします。

Re:質問です

Posted: 2010年3月25日(木) 22:20
by くりあ
>疑問点を整理した上で、十分な情報を添えて再質問されることをお勧めします。

分かりました。グダグダと長くなってしまって申し訳ありませんでした。
自分の頭の中を整理して、もう一度質問し直すことにします。
ここまで答えてくださってありがとうございました。
そして、すいませんでした。次に質問するときは、よろしくお願いします。