constが絡むならstringのコンストラクタ付近で出るだろうし
完全に別のインスタンスになってるこんなところでエラー出るとは思えない
953 :
938:2013/09/12(木) 23:36:07.21
ツールの不具合っぽい方向ですすめることになりました。
いろいろありがとうございました。
954 :
デフォルトの名無しさん:2013/09/14(土) 10:59:23.00
流れ読まずに書くけど、他のオブジェクトへの参照を持つクラスのvectorのpush_bachではまった。
単純化して書くと、
struct person
{
person* p;
person(person* other=0) : p(other) { }
他のメンバ;
};
int main()
{
std::vector<person> Vec;
Vec.push_back(person(0));
Vec.push_back(person(&pV[0]));
Vec.push_back(person(&pV[1]));
・・・
push_backで再アロケートが起こると壊れる。
>>954 単純化(?)よりも、動いて実際に壊れるコードをだしてくれ。
そうじゃなきゃ、なにが問題かなんてわからんだろ。
956 :
デフォルトの名無しさん:2013/09/14(土) 11:16:44.55
>>955 Vec[n].p == &Vec[n-1]
が成り立ってると思ったら、Vec[n].pが指してる場所は消滅している。
reserveしてからpush_backするか、resizeしてから各Vec[i] へ代入しなきゃダメ。
personはデフォルトのコピコンと代入演算子でOKなクラス。
デストラクタで delete p もしてない。
コンテナの要素としての要件は満たしているんだけどね。
そりゃおめえvectorの中身のアドレスなんだから
メモリ上の位置変わっても文句言えねえだろ
なんかおかしくない?
なんでnとn-1が同じところを指すんだか
pVもどこからでて来たかわかんねーし…
コンストラクタに渡されるのは再配置前のアドレスなんだから当たり前だよなぁ
>>958 書き間違い
× Vec.push_back(person(&pV[0]));
× Vec.push_back(person(&pV[1]));
○ Vec.push_back(person(&Vec[0]));
○ Vec.push_back(person(&Vec[1]));
本当に必要だったもの: std::vector<person*>
コレクション要素を指すポインタを保持したり他に渡したりするのは厳禁、
イテレータも有効範囲に注意してし使わなければならない、ってのはSTLを
使い始めてごく初期に学ぶことと思っていたが。
>>962 そうだね。外部イテレータが無効になるのは誰もが意識してるだろうけどね。
今日日、何が悲しくてc++なんて使ってんだろう
>>961 それ、boost::ptr_vectorにしといた方がいい
そんな便利な物があったのか
全然知らんかった
今だったら普通にshared_ptrに包んでvectorに突っ込んだ方が楽だけどな
ptr_vectorって変な制限が多いでしょ
970 :
デフォルトの名無しさん:2013/09/25(水) 15:41:46.87
std::stringのend()って、
必ず末尾のNULL部分なのでしょうか?
>char cLast = *(SBuf.end());
>if (cLast == 0) {
> cLast = *(SBuf.end() -1);
>}
みたいな処理を書いていますが、コンパイラによっては、
1行目で吹っ飛びます(><)
971 :
デフォルトの名無しさん:2013/09/25(水) 15:49:09.49
それ以前に色々間違ってる
973 :
デフォルトの名無しさん:2013/09/25(水) 15:59:01.05
意外と長寿スレだったぬ
974 :
デフォルトの名無しさん:2013/09/25(水) 17:04:28.72
間違ってるなら、正しい記述を教えて下さいorz
end()は例えばCで言うと int a[10]; の a[10] みたいなもんで、アドレスとしては有効だけど
領域が確保されてないので中身にアクセスすると未定義
単にイテレータを比較するためのだけのもの
ちなみにイテレータの比較に < を使わず != を使うのは、random_access_iteratorだけじゃないため
>領域が確保されてないので中身にアクセスすると未定義
有難うございました。
>random_access_iteratorだけじゃないため
今一つ意味が。。。
>>976 例えばstd::listはbidirectional_iteratorなので要素順としては連続していても
アドレスがあべこべの順になっているなんて事はよくある
だから < で比較しない
というか実際に自分で試してみて「あれっ?」と思う体験が大事
>>970 std::string で末尾が NULL なのは c_str() でアクセスした場合。
末尾の文字が欲しい場合は
const char cLast = SBuf.empty() ? 0 : *SBuf.rbegin();
とかする。
空文字列の時に rbegin() を逆参照してはいけないので注意。
君の *(SBuf.end() -1) も空文字列の時にダメ。
*(SBuf.end()) は常にダメ。
'\0' と NULL を混同するんじゃねぇ
>*(SBuf.end()) は常にダメ。
なるほど、STLの.end()って、ここでしか使ったこと無かったんですが、
既にデータの外だよ、
という意味でしたか。
イテレータの実装が単なるポインタのvectorでend()の値が何になるか・・・を考えてみればok
>イテレータの実装が単なるポインタのvectorでend()の値が何になるか・・・を考えてみれば
って、最後の文字のポインタになってて、最後の文字取得出来た方が便利じゃん?
std::stringとc_str()は違うのよん
int main()
{
std::string str("Test");
std::string::const_iterator pos = str.begin();
for (int i = 0; pos != str.end(); i++, ++pos)
std::cout << "str[" << i << "] = " << *pos << std::endl;
for (int i = 0; i < (int)strlen(str.c_str()) + 1; i++) {
std::cout << std::dec << std::noshowbase << "str.cstr[" << i << "] = '\\";
if (str.c_str()[i] == '\0')
std::cout << "0x00' ←Terminate character" << std::endl;
else
std::cout << std::hex << std::showbase << std::setw(4)
<< std::setfill('0') << (int)str.c_str()[i] << "'" << std::endl;
}
}
わざわざendやrbeginを持ち出さなくてもbackがあるわけだが
>>984 そんな事は分かっている
それにrbegin()もあるし
c_str()の場合はどうするんだ?
>>970を見る限り最後の文字を取得したいだけっぽいからback()で十分なんじゃないの?
>>978とかイテレータを経由する意味がまったくわからないし
そんなもん人の勝手だろうが
文句あるんなら自分で書け
中途半端な親切心でレスするのも間違い
親切心ではなくてこの場合は単なる言い掛かり
ム板なら黙って改良版を書いて示して「こっちの方がすっきりしてるだろ」と言う方がいい
>>970 char cLast = SBuf.back();
こっちのほうがすっきりしてるだろ
空文字列のときどうしたいのかはわからないから好きにしろ
991 :
970:2013/09/27(金) 09:09:41.20
>char cLast = SBuf.back();
あ、これで最後の文字が取れるんですか。
これが知りたかったことかもwww
>空文字列のとき
は、size()で判定済みなので、無問題です。
back()はC++11ね
C++03にはない
>back()はC++11ね
orz
だから、*(SBuf.rbegin())でいいじゃないの。
こうしないと空文字列の時未定義の動作
if (SBuf.length())
std::cout << *SBuf.rbegin() << std::endl;
あ、
>SBuf.rbegin()
てのが最後の文字を指して(rってのは、reverseだとオモ)、
>SBuf.begin()
てのが最初の文字を指すんだ。
orz
C++03って細かい所で結構未完成なんだな
C++11で結構詰められている
そりゃ8年も掛けたんだもんな
もうPL/Iどころの騒ぎじゃなくなって来たな
世界最大規模の言語かよ
もっともライブラリを入れたらJavaやC#もすごい規模なんだけど
1000 :
◆Cj98aJOpxg :2013/09/28(土) 06:46:47.54
1001 :
1001:
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。