本文介绍了multiset segfault的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我现在看到一个我无法追踪的错误。它是一个中等大小的程序的一部分,但这是一个小程序 ,展示了gcc上的错误。 (程序代码紧跟在消息底部的 。) 症状如下: %g ++ - 版本 g ++(GCC)3.2.1 [...] %g ++ -W -Wall -pedantic test.cpp %。/ a.out push_back(3402,tian)。 push_back(3401,tian)。 push_back(3405,wu)分段错误 % 因此在multiset :: insert中出现问题。 我对STL不太熟悉,所以我想我在某种程度上滥用了 multiset,但对于我的生活,我无法想象 了解如何或如何修复它。 (TerminalList类的目标是成为一个容器 的终端,但允许非常快速地访问 列表包含某个''音节''或''unino''的终端。我是 使用''lower_bound''和''upper_bound''使用gi提取一个矢量 的终端来自myStrHash的ven音节;请 告诉我你是否能看到更好的方法,但这与段错误无关 ,这就是为什么我剪掉了 来自以下程序的所有内容。) 非常感谢, -Arthur ==代码开始== #include< cstdio> #include< cctype> # include< vector> #include< set> #include< string> using namespace std; struct终端 { int unino; 字符串音节; int d ; 终端(int u,const string& y,int c): unino(u),音节(y),d(c) {} }; struct myStrPred { bool operator()(终端* a,终端* b) {return(a-> syllable) < b->音节); } }; struct TerminalList { void push_back(const Terminal& t) ; typedef multiset< Terminal *,myStrPred> StrHashT; vector< Terminal> myVector; StrHashT myStrHash; }; void TerminalList :: push_back(const Terminal& t) { myVector.push_back(t); 终端* pt =& myVector.back(); printf(" push_back(%04x,%s)", pt-> unino,pt-> syllable.c_str()); fflush(stdout); myStrHash.insert(pt); printf(" .\ n"); } int main() { TerminalList字符; characters.push_back(Terminal(0x3402," tian",1)); characters.push_back(Terminal(0x3401," tian",1)); characters.push_back(终端(0x3405," wu",3)); 返回0; }I''m seeing a bug at the moment that I can''t track down. It''spart of a moderately large program, but here is a small programthat exhibits the bug on gcc. (The program code follows at thebottom of the message.)The symptom is this:% g++ --versiong++ (GCC) 3.2.1[...]% g++ -W -Wall -pedantic test.cpp% ./a.outpush_back(3402,tian).push_back(3401,tian).push_back(3405,wu)Segmentation fault%So it appears something is going wrong in multiset::insert.I''m not very familiar with the STL, so I suppose I''m abusingmultiset in some way, but for the life of me I can''t figureout how, or how to fix it.(The goal of the TerminalList class is to be a containerof Terminals, but to allow very fast access to the list ofTerminals containing a certain ''syllable'' or ''unino''. I''musing ''lower_bound'' and ''upper_bound'' to extract a vectorof Terminals with a given syllable from myStrHash; pleasetell me if you can see a better way, but this is unrelatedto the segfault bug, which is why I snipped the code thatdoes all that from the program below.)Thanks much,-Arthur==code begins==#include <cstdio>#include <cctype>#include <vector>#include <set>#include <string>using namespace std;struct Terminal{int unino;string syllable;int d;Terminal(int u, const string& y, int c):unino(u), syllable(y), d(c){}};struct myStrPred {bool operator() (Terminal* a, Terminal* b){ return (a->syllable < b->syllable); }};struct TerminalList{void push_back(const Terminal& t);typedef multiset<Terminal*, myStrPred> StrHashT;vector<Terminal> myVector;StrHashT myStrHash;};void TerminalList::push_back(const Terminal& t){myVector.push_back(t);Terminal* pt = &myVector.back();printf("push_back(%04x,%s)",pt->unino, pt->syllable.c_str());fflush(stdout);myStrHash.insert(pt);printf(".\n");}int main(){TerminalList characters;characters.push_back(Terminal(0x3402, "tian", 1));characters.push_back(Terminal(0x3401, "tian", 1));characters.push_back(Terminal(0x3405, "wu", 3));return 0;}推荐答案" Arthur J. O''Dwyer" < aj*@nospam.andrew.cmu.edu>写道......"Arthur J. O''Dwyer" <aj*@nospam.andrew.cmu.edu> wrote...我现在看到一个我无法追踪的错误。这是一个中等规模的计划的一部分,但这里有一个小程序,它展示了gcc上的错误。 (程序代码紧随消息的底部。)症状如下: %g ++ --version g ++(GCC)3.2.1 [...] %g ++ -W -Wall -pedantic test.cpp %。/ a.out push_back(3402,tian)。 push_back (3401,田)。 push_back(3405,wu)分段错误% 因此看来multiset :: insert中出现了问题。我'我对STL不是很熟悉,所以我想我在某种程度上滥用了多元化,但对于我的生活,我无法想象如何或如何修复它。 修复它的唯一方法是在调用push_back函数之间插入一些不会改变的东西。我不太确定 推荐什么。一个索引绝对可以,但是那么你需要一个机制来从向量中提取值...... (TerminalList类的目标是容器终端,但允许非常快速地访问包含某个''音节''或''unino''的终端列表。我是使用''lower_bound ''和''upper_bound''从myStrHash中提取具有给定音节的终端的矢量;请告诉我你是否能看到更好的方法,但这是无关的 segfault bug,这就是为什么我剪掉了以下程序所做的所有代码的原因。) 非常感谢, -Arthur = =代码开始== #include< cstdio> #include< cctype> #include< vector> #include< set> #include< string> 使用命名空间std; struct终端 { int unino; 字符串音节; int d; 终端(int u,const string& y,int c): unino(u),syllable(y),d(c) {} }; struct myStrPred { bool operator()(Terminal * a,Terminal * b) {return(a-> syllable< b-> syllable); } }; struct TerminalList { void push_back(const Terminal& t); typedef multiset< Terminal *,myStrPred> ; StrHashT; 向量<终端> myVector; StrHashT myStrHash; }; void TerminalList :: push_back(const Terminal& t) { myVector.push_back(t); 这会使所有引用和指向元素的指针无效 vector _if_ reallocation发生。在你的情况下,重新分配确实不会发生,直到插入第三个元素(可能)。 终端* pt =& myVector.back(); 这里给地址取一个向量的元素。该地址 _can_和_will_将被下一个push_back无效。 printf(" push_back(%04x,%s)", pt-> ; unino,pt-> syllable.c_str()); fflush(stdout); myStrHash.insert(pt); 在这里你试图保留那个地址,下次你打电话给这个函数时,这个地址会变成 无效。 printf( 。$ \\ nn;; } 我会把你的课改写为 ---- --------------------只更改了零件 struct myStrPred { vector< Terminal>&容器; myStrPred(向量<终端>& c):容器(c){} bool operator()(int i1,int i2) {return(container [i1] .syllable< container [i2] .syllable); } }; struct TerminalList { void push_back(const Terminal& t) ; typedef multiset< int,myStrPred> StrHashT; vector< Terminal> myVector; StrHashT myStrHash; TerminalList():myStrHash(myStrPred(myVector)){} }; void TerminalList :: push_back(const Terminal& t) { int next_ind = myVector.size(); myVector.push_back(t); printf(" push_back(%04x,%s)", myVector [next_ind ] .unino,myVector [next_ind] .syllable.c_str()); fflush(stdout); myStrHash.insert(next_ind); printf(" .\ n"); } ------------ -------------------------------------------- int main() {TerminalList characters; characters.push_back(Terminal(0x3402," tian",1)); characters.push_back(Terminal(0x3401) ,tian,1)); characters.push_back(终端(0x3405," wu",3)); 返回0; } I''m seeing a bug at the moment that I can''t track down. It''s part of a moderately large program, but here is a small program that exhibits the bug on gcc. (The program code follows at the bottom of the message.) The symptom is this: % g++ --version g++ (GCC) 3.2.1 [...] % g++ -W -Wall -pedantic test.cpp % ./a.out push_back(3402,tian). push_back(3401,tian). push_back(3405,wu)Segmentation fault % So it appears something is going wrong in multiset::insert. I''m not very familiar with the STL, so I suppose I''m abusing multiset in some way, but for the life of me I can''t figure out how, or how to fix it.The only way to fix it is to insert something that doesn''t changebetween calls to your ''push_back'' function. I am nor really surewhat to recommend. An index should definitely be OK, but thenyou need a mechanism to extract the values from the vector... (The goal of the TerminalList class is to be a container of Terminals, but to allow very fast access to the list of Terminals containing a certain ''syllable'' or ''unino''. I''m using ''lower_bound'' and ''upper_bound'' to extract a vector of Terminals with a given syllable from myStrHash; please tell me if you can see a better way, but this is unrelated to the segfault bug, which is why I snipped the code that does all that from the program below.) Thanks much, -Arthur ==code begins== #include <cstdio> #include <cctype> #include <vector> #include <set> #include <string> using namespace std; struct Terminal { int unino; string syllable; int d; Terminal(int u, const string& y, int c): unino(u), syllable(y), d(c) {} }; struct myStrPred { bool operator() (Terminal* a, Terminal* b) { return (a->syllable < b->syllable); } }; struct TerminalList { void push_back(const Terminal& t); typedef multiset<Terminal*, myStrPred> StrHashT; vector<Terminal> myVector; StrHashT myStrHash; }; void TerminalList::push_back(const Terminal& t) { myVector.push_back(t);This invalidates all references and pointers to elements of thatvector _if_ reallocation occurs. In your case, reallocation doesnot occur until the third element is inserted (probably). Terminal* pt = &myVector.back();Here you take an address to an element of the vector. That address_can_ and _will_ be invalidated by the next push_back. printf("push_back(%04x,%s)", pt->unino, pt->syllable.c_str()); fflush(stdout); myStrHash.insert(pt);Here you attempt to preserve that address which can and will becomeinvalid next time you call this function. printf(".\n"); }I''d rewrite your class as------------------------ Only changed partsstruct myStrPred {vector<Terminal>& container;myStrPred(vector<Terminal>& c) : container(c) {}bool operator() (int i1, int i2){ return (container[i1].syllable < container[i2].syllable); }};struct TerminalList{void push_back(const Terminal& t);typedef multiset<int, myStrPred> StrHashT;vector<Terminal> myVector;StrHashT myStrHash;TerminalList() : myStrHash(myStrPred(myVector)) {}};void TerminalList::push_back(const Terminal& t){int next_ind = myVector.size();myVector.push_back(t);printf("push_back(%04x,%s)",myVector[next_ind].unino, myVector[next_ind].syllable.c_str());fflush(stdout);myStrHash.insert(next_ind);printf(".\n");}-------------------------------------------------------- int main() { TerminalList characters; characters.push_back(Terminal(0x3402, "tian", 1)); characters.push_back(Terminal(0x3401, "tian", 1)); characters.push_back(Terminal(0x3405, "wu", 3)); return 0; } " Arthur J. O''Dwyer" ha escrito: [segfault stuff deleted]"Arthur J. O''Dwyer" ha escrito:[segfault stuff deleted](TerminalList类的目标是成为终端的容器,但允许非常快速地访问包含某个音节或unino的终端列表。我是使用''lower_bound''和''upper_bound' '从myStrHash中提取具有给定音节的终端的矢量请告诉我你是否能看到更好的方法,但这与段错误无关,这就是为什么我从下面的程序中删除了所做的所有代码。) (The goal of the TerminalList class is to be a container of Terminals, but to allow very fast access to the list of Terminals containing a certain ''syllable'' or ''unino''. I''m using ''lower_bound'' and ''upper_bound'' to extract a vector of Terminals with a given syllable from myStrHash; please tell me if you can see a better way, but this is unrelated to the segfault bug, which is why I snipped the code that does all that from the program below.) 我写了一个名为Boost.MultiIndex的库,以便及时发布,可以帮助你构建这种混合的 容器。文档可以参考 http://boost-consulting.com/boost/li...doc/index.html 特别是快速双向列表部分查找" 教程展示了如何构建一个容器,AFAICS,可以有效地替换你的TerminalList。也许这对你有帮助。 问候, $ b $bJoaquínMLópezMu?oz $ b $bTelefónica,Investigación y DesarrolloI''ve written a library called Boost.MultiIndex, to be promptly releasedin Boost 1.32, that can help you construct this sort of hybridcontainers. Documentation can be consulted at http://boost-consulting.com/boost/li...doc/index.htmlIn particular, the section "A bidirectional list with fast lookup" inthetutorial shows how to construct a container that, AFAICS, caneffectively replace your TerminalList. Maybe this is helpful to you.Regards,Joaquín M López Mu?ozTelefónica, Investigación y Desarrollo 2004年6月17日星期四,[iso-8859-1]JoaquínMaLópezMu?oz写道:On Thu, 17 Jun 2004, [iso-8859-1] Joaquín Ma López Mu?oz wrote: Arthur J. O'Dwyer ha escrito: "Arthur J. O''Dwyer" ha escrito:(TerminalList类的目标是成为终端的容器,但是允许非常快速地访问包含某个''的终端列表''音节''或''unino''。 (The goal of the TerminalList class is to be a container of Terminals, but to allow very fast access to the list of Terminals containing a certain ''syllable'' or ''unino''. 我写了一个名为Boost.MultiIndex的库,要在Boost 1.32中及时发布,它可以帮助你构建这种混合容器。文档可以参考 http://boost-consulting.com/boost/li...doc/index.html 特别是教程中的快速查找的双向列表显示了如何构建一个容器,AFAICS可以有效地替换你的TerminalList。也许这对你有帮助。 I''ve written a library called Boost.MultiIndex, to be promptly released in Boost 1.32, that can help you construct this sort of hybrid containers. Documentation can be consulted at http://boost-consulting.com/boost/li...doc/index.html In particular, the section "A bidirectional list with fast lookup" in the tutorial shows how to construct a container that, AFAICS, can effectively replace your TerminalList. Maybe this is helpful to you. 是和否。;-(''multi_index_container''模板*是*确切的 我在找什么;我当然希望Boost成为C ++库支持的至少一个/ b $ b /事实/标准,如果不是 标准本身的一部分!但据我所知,使用''multi_index_container'' 我需要下载并安装* all * of Boost(或至少 大部分内容)所有 上的#include由multi_index_container.hpp包括我打算编译程序的机器。为了我的谦卑目的,那就是多少钱。 :) [因为它们有三个 ,其中一个是Linux系统,我没有管理权限,也没有兆字节的用户空间。] 感谢您引起我的注意;我要去 必须开始看看Boost可以做的其他事情,我一直在做什么。手工制作。也许有一天,我将把所有较大的节目与Boost联系起来,这将是值得的。 同时,我还在想什么'我使用 ''multiset''错了... -ArthurYes and no. ;-( The ''multi_index_container'' template *is* exactlywhat I''m looking for; I certainly hope Boost becomes at least a/de facto/ standard for C++ library support, if not part of thestandard itself! But as I understand it, to use ''multi_index_container''I would need to download and install *all* of Boost (or at least thelarge portion of it #included by multi_index_container.hpp) on allthe machines on which I intended to compile my program. And that''sa little much, for my humble purposes. :) [Being as there are threeof them, and one of them is a Linux system on which I have neitheradministrative privileges nor megabytes of userspace to spare.]Thank you for bringing it to my attention, though; I''m going tohave to start looking at what else Boost can do that I''ve been doingby hand. Maybe one of these days it will become worth my while totie all my larger programs to Boost.Meanwhile, I''m still wondering what''s wrong with my use of''multiset''...-Arthur 这篇关于multiset segfault的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!