由一個莫名其妙的段錯誤引起的探究:如何从函數返回一個 set<>的返回値?

WorldCreater 2011-09-29 12:27:25
class Coordinate3DPoint
{
public:
Coordinate3DPoint();
virtual ~Coordinate3DPoint();
TGMP a, b, c; //TGMP是一個類,,,封裝了大整數運算包 gmplib,運行正常
// TGMP w1, w2, w3, w4, w5, w6;
protected:
private:
};

int main() {


cout << "..........1........." << endl;
Coordinate3DPoint p; //主程序中正常
cout << "............2......." << endl;
}


Coordinate3DPoint Coordinate3DPlane::getAbsoluteDisplacement(const Coordinate3DPoint& o) {
cout << "aaaaaa1111111aaa" << endl;
Coordinate3DPoint r;
cout << "aaaaaa22222222aa" << endl; 第二行無法打印出來,这說明上一行就發生段錯誤了,不知原因所在??

.............
}
...全文
119 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
yisikaipu 2011-09-29
  • 打赏
  • 举报
回复
struct deref_less;
class TGMP;
typedef set<TGMP*, deref_less> TGMPset;

class TGMP
{
public:
int data;
TGMP(int d):data(d){}
TGMPset func();
};

bool operator<(const TGMP x, const TGMP y)
{
return x.data<y.data?true:false;
}

struct deref_less
{
bool operator()(TGMP* p, TGMP* q) const
{
return *p<*q;
}
};

int _tmain(int argc, _TCHAR* argv[])
{
TGMP x(0);
TGMPset s=x.func();

// 清理
for(TGMPset::iterator i=s.begin();i!=s.end();++i) delete *i;
s.clear();

return 0;
}

TGMPset TGMP::func()
{
TGMPset s;

TGMP *t1=new TGMP(4);
TGMP *t2=new TGMP(5);
TGMP *t3=new TGMP(4);

if(!s.insert(t1).second) delete t1;
if(!s.insert(t2).second) delete t2;
if(!s.insert(t3).second) delete t3;

return s;
}
[Quote=引用 13 楼 worldcreater 的回复:]

我是成员函數中要用
// static set<TGMP*, less_tgmp> pollardRHOx(const unsigned long int);
如果這樣則無法編譯

/cpp-test/src/TGMP.cpp|492|error: conversion from ‘std::set<TGMP*, less_tgmp, std::allocator<TGMP……
[/Quote]
WorldCreater 2011-09-29
  • 打赏
  • 举报
回复
由於之前是没有問題的,,,,繼續查看 main 函數最前頭新加入的幾行代码
int main() {
set<TGMP> r;
r = TGMP::pollardRHO(60); //發現是这一行导致後面的代碼出錯,注釋後代碼又正常了
.......
}


set<TGMP> TGMP::pollardRHO(const unsigned long int o) {
set<TGMP> r;

TGMP n, i, x, y, k, d;

n = o;
i = 1;
x = o - 1; //x = TGMP::urandomm(o-1);
y = x;
k = 2;

//一旦到達 x[i] 满足當 j<i 時 x[i]=x[j] 則已處在一個循環中
while (true) {
i = i + 1;
x = (x * x - 1) % n; //x[i] = (x[i-1]^2 - 1) % n
d = TGMP::gcd(y-x, n);

if ((d!=1)&&(d!=n)) {
cout << d.toString() << ", ";
r.insert(d); /////////只在这里用到 返回值
// break;
// cout << "n" << n.toString() << ", i" << i.toString() << ", x" << x.toString() << ", y" << y.toString() << ", k" << k.toString() << ", d" << d.toString() << endl;
} else if (i==k) {
y = x;
k = k * 2;
}
if (i>o) break;
}
cout << endl;
return r; //以及这返回 r
}



於是,注釋掉返回値 return r;
主程序可以運行到最後一行代碼

那麽問題出在 return 上,
想到把 set<TGMP> 設成返回引用 set<TGMP>&
可這樣,,,提示返回局部變量,更不行
WorldCreater 2011-09-29
  • 打赏
  • 举报
回复
我是成员函數中要用
// static set<TGMP*, less_tgmp> pollardRHOx(const unsigned long int);
如果這樣則無法編譯

/cpp-test/src/TGMP.cpp|492|error: conversion from ‘std::set<TGMP*, less_tgmp, std::allocator<TGMP*> >’ to non-scalar type ‘std::set<TGMP*, std::less<TGMP*>, std::allocator<TGMP*> >’ requested|

如果定義中去掉 less_tgmp 只在返回値時定義成
set<TGMP, less_tgmp> r; 則有上述錯誤
yisikaipu 2011-09-29
  • 打赏
  • 举报
回复
参考如下例子
class TGMP
{
public:
int data;
TGMP(int d):data(d){}
};

bool operator<(const TGMP x, const TGMP y)
{
return x.data<y.data?true:false;
}

struct deref_less
{
bool operator()(TGMP* p, TGMP* q) const
{
return *p<*q;
}
};

int _tmain(int argc, _TCHAR* argv[])
{
typedef set<TGMP*, deref_less> TGMPset;

TGMPset s;

TGMP *t1=new TGMP(4);
TGMP *t2=new TGMP(5);
TGMP *t3=new TGMP(4);

if(!s.insert(t1).second) delete t1;
if(!s.insert(t2).second) delete t2;
if(!s.insert(t3).second) delete t3;

// ...

// 清理
for(TGMPset::iterator i=s.begin();i!=s.end();++i) delete *i;
s.clear();

return 0;
}
[Quote=引用 10 楼 worldcreater 的回复:]

不行啊

include/TGMP.h|63|error: ‘less_tgmp’ was not declared in this scope|

這個結構應在哪定義???

我在 TGMP 的頭文件 TGMP 類的前後定義都不行,,,無法編譯

include/TGMP.h|10|error: ‘TGMP’ has not been declared|
[/Quote]
WorldCreater 2011-09-29
  • 打赏
  • 举报
回复
而且,我還發現:在这類中多定義幾個 TGMP 變量时
class Coordinate3DPoint
{
public:
Coordinate3DPoint();
virtual ~Coordinate3DPoint();
TGMP a, b, c;
TGMP w1, w2, w3, w4, w5, w6; //////////多定義幾個
protected:
private:
};

int main () {

cout << "..........1........." << endl;
Coordinate3DPoint p;
cout << "............2......." << endl; //这行無法打印,說明上一行出錯

,,,,,,,,,,,,,,,,,
}

不知这問題在哪?????
simimasaiya 2011-09-29
  • 打赏
  • 举报
回复
学习了……
WorldCreater 2011-09-29
  • 打赏
  • 举报
回复
不行啊

include/TGMP.h|63|error: ‘less_tgmp’ was not declared in this scope|

這個結構應在哪定義???

我在 TGMP 的頭文件 TGMP 類的前後定義都不行,,,無法編譯

include/TGMP.h|10|error: ‘TGMP’ has not been declared|
yisikaipu 2011-09-29
  • 打赏
  • 举报
回复
这个好办,自定义个结构即可解决
struct deref_less
{
bool operator()(TGMP* p, TGMP* q) const
{
return *p<*q;
}
};

set<TGMP*, deref_less> r;
[Quote=引用 8 楼 worldcreater 的回复:]
但隨之也有了新問題——使用 set 的本意也是要保證數據的不重複性
TGMP 類是可以比較的,所以我將返回類型定義成
set<TGMP*, less<TGMP*> > 但没有達到目的,,,重複的數據全部存入了
[/Quote]
WorldCreater 2011-09-29
  • 打赏
  • 举报
回复
發現了,在放入 set 前需要 new 一個 TGMP

這樣,也許用這位仁兄的方法可能要好點,
但隨之也有了新問題——使用 set 的本意也是要保證數據的不重複性
TGMP 類是可以比較的,所以我將返回類型定義成
set<TGMP*, less<TGMP*> > 但没有達到目的,,,重複的數據全部存入了

[Quote=引用 7 楼 yisikaipu 的回复:]

强烈建议使用set<TGMP*>
[/Quote]
    set<TGMP*, less<TGMP*> > r;
r = TGMP::pollardRHO(60);
cout << r.size() << endl;
set<TGMP*, less<TGMP*> >::iterator it = r.begin();
while (it != r.end()) {
cout << ((TGMP*)*it)->toString() << " ";
it++;
}
cout << endl;


使用指針時,取出數據的方法我知道,已成功運行

如果返回 set<TGMP> 的話還没試驗成功

存入方法:

TGMP* t = new TGMP();
*t = d;
r.insert(*t); ///返回値設成 set<TGMP> 時的

取出時使用 (TGMP)it 或 (TGMP)*it 都没成功
yisikaipu 2011-09-29
  • 打赏
  • 举报
回复
强烈建议使用set<TGMP*>
WorldCreater 2011-09-29
  • 打赏
  • 举报
回复
C++中的 SET 是接口還是類???

好象是類吧???
WorldCreater 2011-09-29
  • 打赏
  • 举报
回复
而且有這個條件在 if (i>o) break; 肯定是不會死循環的,,,,

繼續調試後發現, r.insert(d) 語句有問題,注釋掉後,程序正常。。。。。

开啟後就有 段錯誤 

而且,奇怪地, 它并不是立即就有問題,

在主程序中 r = TGMP::pollardPHO(60)後 還能運行好幾行代码 才打印 “段錯誤” 
WorldCreater 2011-09-29
  • 打赏
  • 举报
回复
可問題是,我把 pollardPHO 設成無返回値 void 時,是正常的
星羽 2011-09-29
  • 打赏
  • 举报
回复
set的是可以返回的,你cout失败,是不是你前面直接死循环了- -
WorldCreater 2011-09-29
  • 打赏
  • 举报
回复
不好意思,我弄错了,,,,那是我在程序中打印的,,,,,
WorldCreater 2011-09-29
  • 打赏
  • 举报
回复
還是一样,,放了许多重复數據



struct less_tgmp; //使用 typedef struct less_tgmp; 也一样

class TGMP
{
... ....
static set<TGMP*, less_tgmp> pollardRHOx(const unsigned long int);
protected:
private:
mpz_t value;
};

struct less_tgmp {
bool operator()(TGMP* p, TGMP* q) const {
return *p<*q;
}
};






set<TGMP*, less_tgmp> TGMP::pollardRHOx(const unsigned long int o) {
set<TGMP*, less_tgmp> r;

TGMP n, i, x, y, k, d;


n = o;
i = 1;
x = o - 1; //x = TGMP::urandomm(o-1);
y = x;
k = 2;


//一旦到達 x[i] 满足當 j<i 時 x[i]=x[j] 則已處在一個循環中
while (true) {
i = i + 1;
x = (x * x - 1) % n; //x[i] = (x[i-1]^2 - 1) % n
d = TGMP::gcd(y-x, n);

if ((d!=1)&&(d!=n)) {
cout << d.toString() << ", ";

TGMP* t = new TGMP();
*t = d;
r.insert(t);
// break;
// cout << "n" << n.toString() << ", i" << i.toString() << ", x" << x.toString() << ", y" << y.toString() << ", k" << k.toString() << ", d" << d.toString() << endl;
} else if (i==k) {
y = x;
k = k * 2;
}
if (i>o) break;
}
// cout << endl;
return r;
}


yisikaipu 2011-09-29
  • 打赏
  • 举报
回复
存指针当然是比较麻烦的,但如果难以保证TGMP的简单,这点麻烦是值得的
yisikaipu 2011-09-29
  • 打赏
  • 举报
回复
全部按你的命名
struct less_tgmp;
class TGMP;
typedef set<TGMP*, less_tgmp> TGMPset;

class TGMP
{
public:
int data;
TGMP(int d):data(d){}
static TGMPset func();
};

bool operator<(const TGMP x, const TGMP y)
{
return x.data<y.data?true:false;
}

struct less_tgmp
{
bool operator()(TGMP* p, TGMP* q) const
{
return *p<*q;
}
};

int _tmain(int argc, _TCHAR* argv[])
{
TGMPset s=TGMP::func();

// 清理
for(TGMPset::iterator i=s.begin();i!=s.end();++i) delete *i;
s.clear();

return 0;
}

TGMPset TGMP::func()
{
TGMPset s;

TGMP *t1=new TGMP(4);
TGMP *t2=new TGMP(5);
TGMP *t3=new TGMP(4);

if(!s.insert(t1).second) delete t1;
if(!s.insert(t2).second) delete t2;
if(!s.insert(t3).second) delete t3;

return s;
}
[Quote=引用 13 楼 worldcreater 的回复:]

我是成员函數中要用
// static set<TGMP*, less_tgmp> pollardRHOx(const unsigned long int);
如果這樣則無法編譯

/cpp-test/src/TGMP.cpp|492|error: conversion from ‘std::set<TGMP*, less_tgmp, std::allocator<TGMP……
[/Quote]

64,646

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧