multiset segfault [英] multiset segfault

查看:61
本文介绍了multiset segfault的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我现在看到一个我无法追踪的错误。它是一个中等大小的程序的一部分,但这是一个小程序

,展示了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;
< br $>
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''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 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);
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 change
between calls to your ''push_back'' function. I am nor really sure
what to recommend. An index should definitely be OK, but then
you 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 that
vector _if_ reallocation occurs. In your case, reallocation does
not 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 become
invalid next time you call this function.

printf(".\n");
}
I''d rewrite your class as

------------------------ Only changed parts
struct 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的库,以便及时发布< Boost 1.32中的
,可以帮助你构建这种混合的

容器。文档可以参考

http://boost-consulting.com/boost/li...doc/index.html


特别是快速双向列表部分查找"



教程展示了如何构建一个容器,AFAICS,可以有效地替换你的TerminalList。也许这对你有帮助。


问候,

$ b $bJoaquínMLópezMu?oz
$ b $bTelefónica,Investigación y Desarrollo



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.

Regards,

Joaquín M López Mu?oz
Telefó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''错了...


-Arthur



Yes and no. ;-( The ''multi_index_container'' template *is* exactly
what I''m looking for; I certainly hope Boost becomes at least a
/de facto/ standard for C++ library support, if not part of the
standard itself! But as I understand it, to use ''multi_index_container''
I would need to download and install *all* of Boost (or at least the
large portion of it #included by multi_index_container.hpp) on all
the machines on which I intended to compile my program. And that''s
a little much, for my humble purposes. :) [Being as there are three
of them, and one of them is a Linux system on which I have neither
administrative privileges nor megabytes of userspace to spare.]
Thank you for bringing it to my attention, though; I''m going to
have to start looking at what else Boost can do that I''ve been doing
by hand. Maybe one of these days it will become worth my while to
tie all my larger programs to Boost.

Meanwhile, I''m still wondering what''s wrong with my use of
''multiset''...

-Arthur


这篇关于multiset segfault的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆