2 zhulupeng7468 zhulupeng7468 于 2016.05.17 12:01 提问

高分悬赏,求求大神帮忙解答一下,快崩溃了 4000C

代码编译连接都ok,运行半天最后报错 ,就是调用 计算数乘nP的函数Point_Multiply 时就卡住了,单步跟踪到这就执行不下去了。
调试怀疑是内存溢出,水平有限,希望大神们帮帮我

  Point Point_Calculate(Point P,Point Q) //点加和倍点加
{
    BigInteger r,temp0(0),temp2(2),temp3(3);
    Point R;
    if (Compare(P.x)&&Compare(P.y))
    {
        R=Q;return R;
    }
    else if (Compare(Q.x)&&Compare(Q.y))
    {
        R=P;return R;
    }
    else if (Compare(P.x,Q.x)) 
    {
        r=(Q.y-P.y)*Inv(Q.x-P.x,q)%q;
    }
    else if (Compare(P.y,Q.y)) 
    {
        R.x=R.y=temp0;return R;
    }
    else if (Compare(Q.y))
    {
        R.x=R.y=temp0;return R;
    }
    else
    {
        r=(temp3*P.x*P.x+a)*Inv(temp2*P.y,q)%q;
    }

    R.x=(r*r%q-P.x-Q.x)%q;
    if (Compare(R.x,temp0)==-1)
    {
        R.x=R.x+q;
    }
    R.y=(r*(P.x-R.x)-P.y)%q;
    if (Compare(R.y,temp0)==-1)
    {
        R.y=R.y+q;
    }
    return R;
}
//计算数乘nP,采用重复平方法计算
Point Point_Multiply(Point P,BigInteger n)
{
    Point result;
    BigInteger temp,temp2(2),temp0(0);
    int b[160],count;
    result.x=result.y=temp0;//初始化为O点
    n.BigNumToIndex(b,count);//得到n的二进制表示
    //按重复平方法求解nP
    for(int i=count-1;i>=0;i--)
    {
        result=Point_Calculate(result,result);
        if (b[i])
        {
            result=Point_Calculate(result,P);
        }
    }
    return result;
}

//将大整数转化为二进制数,并不影响*this的值
void BigInteger::BigNumToIndex(int b[],int &count)
{
    BigInteger BigNum=*this,temp2(2),temp;
    count=0;
    while (int(BigNum.Head->Num))
    {
        temp=BigNum%temp2;
        b[count++]=int(temp.Head->Num);
        BigNum=BigNum/temp2;
    }
}

//大整数的定义
BigInteger::BigInteger()        //构造函数,将每个节点置空
{
    Head=End=TempNode=NULL;
}

BigInteger::BigInteger(char i)  //构造函数,只拥有一位的大整数
{
    Head=End=TempNode=NULL;
    TempNode=new Node;
    TempNode->Num=i;
    TempNode->Prev=NULL;
    Head=End=TempNode;
    TempNode->Next=NULL;    
}

BigInteger::BigInteger(const BigInteger &BigNum)     //拷贝构造
{
    Node *p;
    Head=End=TempNode=NULL;
    p=BigNum.Head;
    while(p)
    {
        AddEnd(p->Num);
        p=p->Next;
    }
}

BigInteger::~BigInteger()        //析构
{
    Node *NextNode;
    if(Head==NULL)
        return;
    TempNode=Head;
    while(TempNode)
    {
        NextNode=TempNode->Next;
        delete TempNode;
        TempNode=NextNode;
    }
    Head=NULL;
    End=NULL;
    TempNode=NULL;
}

void BigInteger::AddHead(char Num)        //在链表头插入节点的操作
{
    TempNode=new Node;
    TempNode->Num=Num;
    TempNode->Prev=NULL;
    if(!Head)
    {
        Head=End=TempNode;
        TempNode->Next=NULL;
    }
    else
    {
        TempNode->Next=Head;
        Head->Prev=TempNode;
        Head=TempNode;
    }
}

void BigInteger::AddEnd(char Num)       //在链表尾插入节点的操作
{
    TempNode=new Node;
    TempNode->Num=Num;
    TempNode->Next=NULL;
    if(!Head)
    {
        Head=End=TempNode;
        TempNode->Prev=NULL;
    }
    else
    {
        TempNode->Prev=End;
        End->Next=TempNode;
        End=TempNode;
    }
}

27个回答

qq_35485029
qq_35485029   2016.07.05 11:23

是的 确实是内存溢出, BigInteger太啰嗦了,把4000c先给我,我问下我朋友,他是弄这一块的!!!

love8698
love8698 给我4000c,我晚上上香,去问问炎总,他就是干这一块的。
大约 2 个月之前 回复
iFleetingtime
iFleetingtime 给我4000c,我晚上上香,去问问乔布斯,他就是干这一块的。
大约 2 个月之前 回复
hahazpf
hahazpf 给我4000 我也去问问我朋友 他在建筑工地搬砖
2 个月之前 回复
vitamins929
vitamins929 呵呵
3 个月之前 回复
qq_35384853
qq_35384853 给我4000c,我去问我朋友,相信我
3 个月之前 回复
Smith_My_
Smith_My_ 给我4000c,我去问你朋友
大约一年之前 回复
lyyybz
lyyybz 相信你 才怪
一年多之前 回复
qq_35485029
qq_35485029 给我4000c,我去问我朋友
一年多之前 回复
qq_35485029
qq_35485029 相信我
一年多之前 回复
beau_lily
beau_lily   2017.11.09 16:35

我就看看 说不定采纳我为最佳答案了呢

a772874637
a772874637 大范围的说法
大约 2 个月之前 回复
caozhy
caozhy 看楼主的样子,好像他的c币也是刷的。
3 个月之前 回复
caozhy
caozhy 然而楼主是不会来了
3 个月之前 回复
lbcab
lbcab   2016.05.17 13:03

你的Point中的两个点的值的类型是BigInteger ? 你每次去做一些操作的时候都会使用point来保存你的值, 这样无形中就copy了多份
for(int i=count-1;i>=0;i--)
{
result=Point_Calculate(result,result); //这里就会copy count份 point的值, 而这时虽然是把值付给同一个对象result, 但是却new了多次,
//我觉得你应该将Point_Calculate的返回类型改为引用
if (b[i])
{
result=Point_Calculate(result,P);
}
}

    以上结论的前提是你的Point中的点是BigInteger类型.  不一定对, 可以参考一下.
qq_38808984
qq_38808984 是的 确实是内存溢出, BigInteger太啰嗦了,把4000c先给我,我问下我朋友,他是弄这一块的!!!
大约一个月之前 回复
lbcab
lbcab 回复zhulupeng7468: temp=BigNum%temp2 这个操作有实现? temp2的值是多少? 它初始化调用的构造函数是那个? 我看你贴的代码没有类似的构造, 而且你BigInteger中的参数类型是char
接近 2 年之前 回复
zhulupeng7468
zhulupeng7468 不太对,代码还没运行到这就报错了,每次运行到 n.BigNumToIndex(b,count);//得到n的二进制表示,就报错了,还是很感谢您
接近 2 年之前 回复
VisualEleven
VisualEleven   Ds   Rxr 2016.05.17 13:58

如果怀疑是内存溢出的问题,你可以打开任务管理,看看内存的使用情况,运行一段时间,看看内存大小是否是只增不减~

zhulupeng7468
zhulupeng7468 是的 确实是内存溢出 您会解决吗?
接近 2 年之前 回复
naivor
naivor   2016.05.17 22:13

哇,好多c币,可惜我C++忘得差不多了。。。。

henuyx
henuyx   2016.06.22 13:33

代码不够全,可以发过来给你跑一下试试。
你可以查看一下在程序crash的时候,上下文中的参数值都是什么。打开core dump.

u011606457
u011606457   2016.06.02 15:34

是你数据结构设计的不合理:
你用双向链表表示BigInteger,每位数字用一个char表示,占用一个字节;
还要计算链表的前向、后向两个指针大小,以及包装对象Node的大小,
如果遇到很大在整数时非常占用内存。

你可以去参考java里面BigInteger的实现,内存占用就很少了。

针对你的实现,我也可以给点优化建议:
把Node对象做成不可变对象,其实就只有0-9 10种Node,不需要每次都new Node对象,这样就可以节约很大部分的内存了。

qq_35485029
qq_35485029 回复_1_1_7_: 不对
一年多之前 回复
u011606457
u011606457 10种Node对象缓存起来,每次直接取对应的数字,不需要每次去new 对象
一年多之前 回复
hyp520520
hyp520520   2016.08.13 08:28

你把数据的存储在优化一下,或是全局变量都要用的话,就设置成static,不需要的话,用完之后直接进垃圾站

baidu_24473805
baidu_24473805   2017.06.06 16:24

大家看看我的问题好不好,不要只想着c币

Drizzly_
Drizzly_   2017.11.22 10:37

我就看看 说不定采纳我为最佳答案了呢

共27条数据 1 3 尾页
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!