[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 2chのread.cgiへ]
Update time : 06/27 01:24 / Filesize : 192 KB / Number-of Response : 847
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

【C++】STL(Standard Template Library)相談室 9



1 名前:デフォルトの名無しさん [2008/02/27(水) 02:03:30 ]
C++標準ライブラリの一つ、STLについて。

前スレ
【C++】STL(Standard Template Library)相談室 8
pc11.2ch.net/test/read.cgi/tech/1198435319/

過去ログ・リンク・書籍紹介は >>2 以降

784 名前:デフォルトの名無しさん [2008/06/24(火) 20:00:11 ]
vectorの要素を指すポインタは無効になることがあります。
では、queueの要素を指すポインタは無効になることがありますか?
下のプログラムを実行すると、1 2 4 4 5 6 と出力され、期待通りに動きました。
このプログラムは正しいプログラムですか?

#include <iostream>
#include <queue>
using namespace std;

int main()
{
  queue<int> q;
  q.push(1);
  q.push(2);
  q.push(3);  int* x = &q.back();
  q.push(4);
  q.push(5);
  q.push(6);
  (*x)++;

  while (!q.empty()) {
    cout << q.front() << ' ';
    q.pop();
  }
  return 0;
}


785 名前:デフォルトの名無しさん mailto:sage [2008/06/24(火) 20:11:36 ]
>>784
queueの中身のデフォはdequeなので、要素追加で
リアロケートが発生することがある。ポインタもイテレータも無効になる。



786 名前:784 mailto:sage [2008/06/24(火) 21:00:22 ]
>>785
なるほど。ありがとうございます。危ないところでした。

では、リストを使って、queue<int, list<int> > q;
とすればOKでしょうか?

787 名前:デフォルトの名無しさん mailto:sage [2008/06/24(火) 21:30:01 ]
>>785
途中への追加はイテレータ等が無効になる可能性があるけど
端への追加ではイテレータ等は無効になんないんじゃないの?

788 名前:デフォルトの名無しさん mailto:sage [2008/06/24(火) 21:46:06 ]
>>787
> 23.2.1.3 deque modifiers
> An insert at either end of the deque invalidates all the iterators to the deque,
> but has no effect on the validity of references to elements of the deque.

イテレータは無効になるが、要素への参照は有効のまま。

789 名前:デフォルトの名無しさん mailto:sage [2008/06/25(水) 09:16:26 ]
>>786
vectorやdequeなら、イテレータではなく添え字でアクセスするのも有り。

790 名前:デフォルトの名無しさん [2008/06/28(土) 14:03:55 ]
algorithmのcopyについての質問です。

ifstream ifs(argv[1]);
vector<char> file;
copy(
 istream_iterator<char>(ifs.seekg(10, ios_base::beg))
 istream_iterator<char>(ifs.seekg(20, ios_base::beg))
 back_inserter(file)
);

上記のようなコードで、あるファイルの10バイト目から20バイト目までをコピーしようとおもったのですが、出来ませんでした。
このような事をする場合はどうしたらいいのでしょうか?

791 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 15:14:14 ]
>>790
int const begin = 10;
int const end = 20;

ifs.seekg(begin);
int const length = end - begin;
file.resize(length);
ifs.read(&file[0], length);

792 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 15:21:29 ]
>>791
ありがとう、だけどファイル以外のストリームに対しても同じ方法がとりたいとおもっているので、
algorithmのcopy、あるいはSTLの何かを使って解決したいのです。
で、思いついたのが790のコードなのです。



793 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 17:36:54 ]
>>792
>791 はファイル以外のストリームにも使えるんじゃないか?
seekg() ができないかもしれないってこと?

794 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 17:41:54 ]
そういや copy_n() ほしいな。

795 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 20:43:54 ]
どうでもいいけどistream_iterator<char>使うな
istreambuf_iterator<char>使え

istream_iterator<char>はoperator>>で入力するから、空白とか
スキップする。コピーにならんぞ

796 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 20:57:41 ]
どうでもいい割には念を押すね。

797 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 21:09:48 ]
>>795
それ「どうでもいい」事じゃないと思うw

798 名前:デフォルトの名無しさん mailto:sage [2008/06/29(日) 22:25:50 ]
あげあしはどうでもいいよ。

799 名前:デフォルトの名無しさん mailto:sage [2008/06/30(月) 00:24:58 ]
揚げ足取り、って言いたかったのかな。

800 名前:デフォルトの名無しさん mailto:sage [2008/06/30(月) 00:30:10 ]
手羽先、って言いたかったんたと思うよ

801 名前:デフォルトの名無しさん mailto:sage [2008/06/30(月) 01:44:47 ]
コケコッコーーー!!!

802 名前:デフォルトの名無しさん mailto:sage [2008/06/30(月) 08:15:27 ]
お前ら鳥類食ってて何も恥じらいはないのかよ。
哺乳類としてのプライドはどこへ



803 名前:デフォルトの名無しさん mailto:sage [2008/06/30(月) 08:54:17 ]
意味不明

804 名前:デフォルトの名無しさん mailto:sage [2008/06/30(月) 09:01:33 ]
つーか、ヘビとかトカゲとか、哺乳類を食うのは許せないよな。
やつら爬虫類が生まれた頃にはまだ哺乳類も鳥類も居なかったってのに。
赤外線センサーまでつけやがって。

805 名前:デフォルトの名無しさん mailto:sage [2008/06/30(月) 16:22:47 ]
面白いと思って書いてるのかな

806 名前:デフォルトの名無しさん mailto:sage [2008/06/30(月) 18:24:07 ]
鳥類爬虫類は許せるが
鯨だけは愛と権利が与えられるべきだと思います


STL

807 名前:デフォルトの名無しさん mailto:sage [2008/06/30(月) 18:27:03 ]
何故か日本より沢山偶然鯨が掛かる隣の国には抗議しません


808 名前:デフォルトの名無しさん mailto:sage [2008/06/30(月) 19:09:10 ]
何でこんな流れに

809 名前:デフォルトの名無しさん mailto:sage [2008/07/01(火) 21:42:20 ]
みんな鳥類食ってて何も恥じらいもないからだと思う

810 名前:デフォルトの名無しさん mailto:sage [2008/07/01(火) 21:49:13 ]
牛食うのは禁止すべきだろ。

811 名前:デフォルトの名無しさん mailto:sage [2008/07/01(火) 23:20:25 ]
人食いてぇ

812 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 02:02:12 ]
通報しますた



813 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 02:11:21 ]
考え方を変えるんだ
そこにシニカルなアーティクルか精神的原論を見出せるかどうかを試してから通報すべきだ
日本は民主主義社会だっていってたよ確か誰かが
毎日と朝日の新聞見ながら泡噴きながら

人食いてぇ=女の子監禁してぇ
人(で)食いてぇ=女の子換金してぇ
人=幼女
人=稚児
人=人

通報しますた

814 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 07:41:04 ]
お前らSTLの話しろよ。
鳥類とか哺乳類とか人間とかあんまり関係ないだろ。

815 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 09:19:26 ]
>>813
通報されないように気を付けて。

ところで、map<int,bar*> mに挿入する時、
m.insert(map<int,foo*>::value_type(0, new foo))とか
m[0]=new fooとか
するのはヤバいよね。
スマポ使えない状況でどう書くのが一番スマートですか?

816 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 10:17:56 ]
foo* p = new foo;

try
{
 m.insert(map<int,foo*>::value_type(0, p));
 // m[0] = p;
}
catch(...)
{
 delete p;
 throw;
}

817 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 10:19:22 ]
まずmap<int,bar*>のbar*を、直接 opertaor =(bar *ptr) 出来ないようなクラスに置き換える。
・map<int, test<bar> >

後はしらね。勝手に適当にメソッドでnewが隠蔽されるようなものでも書けば良いと思うよ。

818 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 11:20:34 ]
>>812
たった今>>811に食われたじゃないか


819 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 11:56:46 ]
foo* p = new foo();
if (!map.insert(std::make_pair(0, p)).second) {
 delete p;
 p = 0;
}

820 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 12:03:46 ]
p = repinterpret_cast<void*>(0);

821 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 12:18:09 ]
>>819
insertで例外起きたらメモリリークするでよ

822 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 13:35:58 ]
>>816
それだと m[0] に既存のポインタが入っていた場合にリークする。
↓これでいいかな?

foo* p = new foo;
try
{
&nbps; foo*& in = m[n];
&nbps; delete in;
&nbps; in = p;
}
catch (...)
{
&nbps; delete p;
&nbps; throw;
}

「スマポ使えない」と言ってもさすがに auto_ptr は使えるだろうから、
↓こっちのがいいと思う。

std::auto_ptr<foo> p(new foo);
foo*& in = m[n];
delete in;
in = p.release();



823 名前:822 mailto:sage [2008/07/02(水) 13:37:02 ]
うわ。 nbsp ミスった。最初のコード訂正。

foo* p = new foo;
try
{
  foo*& in = m[n];
  delete in;
  in = p;
}
catch (...)
{
  delete p;
  throw;
}

824 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 20:34:55 ]
foo * p = new foo;
try {
std::swap(p, m[0]);
delete p;
}
catch(...) {
delete p;
throw;
}

825 名前:デフォルトの名無しさん mailto:sage [2008/07/03(木) 01:52:19 ]
関数内クラスでauto_ptrもどきを自作すればいいんじゃね?

簡単に
pair<map<int,bar*>::iterator, bool> ib(map.insert(std::make_pair(0, 0)));
if (ib.second)
  ib.first.second = new foo;
でも良い気がするけど。

826 名前:デフォルトの名無しさん mailto:sage [2008/07/05(土) 23:35:18 ]
こんばんは。g++でtr1::unordered_setを使おうと思ったのですが。
tr1::unordered_set< vector<unsigned char> >とすると
‘struct std::tr1::hash<std::vector<unsigned char, std::allocator<unsigned char> > >’
と怒られてしまいます。これは何が悪いのでしょうか?
(vector用のhash関数を自分で作る必要があるということでしょうか?)

827 名前:デフォルトの名無しさん [2008/07/05(土) 23:41:48 ]
すいませんage忘れました。

828 名前:デフォルトの名無しさん mailto:sage [2008/07/06(日) 03:22:08 ]
>>826
コードとエラーメッセージをちゃんと貼れ。

829 名前:デフォルトの名無しさん mailto:sage [2008/07/08(火) 04:21:23 ]
デバッガとかでさ、変数名長すぎでしょ。
もう嫌だ。

830 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 17:51:42 ]
#include <iostream>
#include <vector>
using namespace std;

class A {
int val;
public:
A(){cout<<"new"<<endl;}
~A(){cout<<"delete"<<endl;}
void setval(int x){ val = x; }
int getval(void){ return val; }
};

int main () {
A a;
vector<A> list;
cout <<"------------------------------------ Line1"<< endl;
for ( int i=0; i<5; ++i ) {
a.setval( i );
list.push_back( a );
}
cout <<"------------------------------------ Line2"<< endl;
//cout << "size:\t\t" << list.size() << endl;
//cout << "list[data,3]:\t" << list[data, 3] << endl;
for ( unsigned int i=0; i<list.size(); ++i ) {
cout<< list[a,i].getval() << endl;
}
cout <<"------------------------------------ Line3"<< endl;
list.clear();
cout <<"------------------------------------ Line4"<< endl;
return 0;
}

831 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 17:54:23 ]
Line1とLine2の間の
push_backのリサイズ時では何が起こっているのでしょうか

832 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 18:14:06 ]
capacityが要素を保持するのに足りなければ、メモリの再確保が起きている。



833 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 18:46:38 ]
ということは、一度破棄していると言うことでしょうか

834 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 19:57:59 ]
そのクラスAにコピーコンストラクタも書いてみ

835 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 20:48:24 ]
A(const A &obj){cout<<"copy"<<endl;} と
push_back後に1loopの目安として新しく
cout<<"----------------------------------"<<endl;
を付け足して走らせてみたところ

Line1とLine2の間の"copy"と"delete"の表示が
copy がpushした回数+1
deleteがpushした回数
になりました。

copyの回数が+1なのが気になります。
入れる側の参照+listに入っている数と考えそうになりましたが
これでサイズを比べて足りないようなら再確保…と考えるのは変よですね
copyとdeleteの順番と回数を考えると
前のvectorから入っている分コピーした回数+付け足す側からコピーの一回分
という事でしょうか

836 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 20:58:59 ]
あれ、ちょっと変ですね…3回目のプッシュで考えると
既にpushされているのが2個なので

copy  ←コピーしようとした
ここでサイズが足りないので再確保
copy  ←コピーしようとした
copy  ←前のvectorからコピー
copy  ←前のvectorからコピー
delete ←入れようとした時のテンポラリの破棄?
delete ←前のvectorに入ってるのを破棄
delete ←前のvectorに入ってるのを破棄
でしょうか、なんだか混乱してきました…。

837 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 21:23:27 ]
ここでサイズが足りないので再確保
copy  ←前のvectorからコピー
copy  ←前のvectorからコピー
copy  ←前のvectorからコピー
copy  ←新しい要素のコピー
delete ←前のvectorに入ってるのを破棄
delete ←前のvectorに入ってるのを破棄
delete ←前のvectorに入ってるのを破棄

だろ。まぁ新しい要素をどこでコピーするかは実装依存だろうが。
valの値も表示させれば分かるべ。

838 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 21:43:28 ]
それが4回目のpush_backなら納得できるのですが
3回目のpush_backでcopyが4つ表示されているので混乱しています。

839 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 21:49:50 ]
iが3だから3回目とか勘違いしてないか?

840 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 21:54:59 ]

copy
copy
delete
-----------0
copy
copy
copy
delete
delete
delete
-----------1
copy
copy
copy
copy
delete
delete
delete
-----------2

こう表示されています
環境は VC++2005EE +SDK win2000 です

841 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 21:56:29 ]
class A {
int val;
public:
A(){val=0,cout<<"new"<<endl;}
A(const A &obj){cout<<"copy"<<endl;}
~A(){cout<<"delete"<<endl;}
void setval(int x){ this->val = x; }
int getval(void){ return val; }
};


cout <<"------------------------------------ Line1"<< endl;
for ( int i=0; i<5; ++i )
{
a.setval( i );
list.push_back( a );
cout<<"----------------------------------"<< i <<endl;
}
cout <<"------------------------------------ Line2"<< endl;


ソースはこうなってます

842 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 22:03:30 ]
copy
----------------------------------0
copy
copy
delete
----------------------------------1
copy
copy
copy
delete
delete
----------------------------------2

うちではこうなった。
VC++2008EE

forループ入る前にvectorになんか入れてない?
size()の値表示させてみ。



843 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 22:06:00 ]
これが全文です。
#include <iostream>
#include <vector>
using namespace std;
class A {
int val;
public:
A(){val=0,cout<<"new"<<endl;}
A(const A &obj){cout<<"copy"<<endl;}
~A(){cout<<"delete"<<endl;}
void setval(int x){ this->val = x; }
int getval(void){ return val; }
};

int main (){
A a;
vector<A> list;
cout <<"------------------------------------ Line1"<< endl;
for ( int i=0; i<5; ++i ){
a.setval( i );
list.push_back( a );
cout<<"----------------------------------"<< i <<endl;
}
cout <<"------------------------------------ Line2"<< endl;
for ( unsigned int i=0; i<list.size(); ++i ) {
cout<< list[a,i].getval() << endl;
}
cout <<"------------------------------------ Line3"<< endl;
list.clear();
cout <<"------------------------------------ Line4"<< endl;
return 0;
}

844 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 22:36:38 ]
2005入れてないから2003でやってみたらそうなった。
ソース追ってみると、追加する要素を一旦ローカル変数にコピーしてた。
その変数のコピーと破棄が1回ずつ多いみたい。
2005のソースはわからんが多分同じ理由だろう。

845 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 22:41:38 ]
なるほど、これで胸のつかえが取れました
付き合ってくれた皆さん、本当にありがとうございました。

846 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 23:04:39 ]
>>844
>追加する要素を一旦ローカル変数にコピーしてた。

list.push_back( list[3] );






[ 新着レスの取得/表示 (agate) ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<192KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef