zhulupeng7468
2016-05-17 04:01
采纳率: 0%
浏览 9.5k

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

代码编译连接都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;
    }
}

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

22条回答 默认 最新

  • lbcab 2016-05-17 05: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类型.  不一定对, 可以参考一下.
    
    打赏 评论
  • Eleven 2016-05-17 05:58

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

    打赏 评论
  • _1_1_7_ 2016-06-02 07:34

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

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

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

    打赏 评论
  • Heart09 2016-06-22 05:33

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

    打赏 评论
  • hyp520520 2016-08-13 00:28

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

    打赏 评论
  • 码界一棵葱 2016-08-20 01:30

    把出错的堆栈信息贴出来

    打赏 评论
  • 王牧天 2016-09-23 09:13

    这是的话多长时间才能赚到你的这单

    打赏 评论
  • number__ 2016-09-30 05:56

    10种Node对象缓存起来,每次直接取对应的数字,不需要每次去new 对象

    打赏 评论
  • 微wx笑 2017-07-11 04:37

    你好, Point_Multiply 有具体实现代码,单步跟踪到这就执行不下去了。
    1、具体是执行到哪一行卡住的?
    2、是不是条件问题出现了死循环?
    3、怀疑内存溢出,有没有关注内存的变化确认呢?
    4、CPU占用是否正常?

    打赏 评论
  • john_liqinghan 2017-11-14 06:59

    //将大整数转化为二进制数,并不影响*this的值
    void BigInteger::BigNumToIndex(int b[],int &count)
    {
    BigInteger BigNum=*this,temp2(2),temp;
    count=0;
    while (int(BigNum.Head->Num))
    {
    //temp不是一个BigInteger的变量吗?你这个%求于是怎么回事?%这个求于只能对于普通变量进行操作吧?
    // 这段代码看起来头昏脑涨的。
    temp=BigNum%temp2;
    b[count++]=int(temp.Head->Num);
    BigNum=BigNum/temp2;
    }
    }

    打赏 评论
  • 随幻 2017-11-15 05:31

    我说 你敢不敢调试到第几层循环 或者说更详细点的信息 在哪卡住了告诉我们
    就说个函数卡住 那情况多了。。。。
    大部分人是不会去拿你的代码运行去找的 都是眼睛当Debug用

    打赏 评论
  • 小牛宝 2017-11-23 01:34

    你的代码写得不规范,先规范了代码再说吧,假设你需要使用实参传入的值去进行多重比较运算,你得这么干
    public int ( int x,int y){

    int x1=x;
    int y1 =y;
    if(x1==y1||x1+y1>y1||x1-y1<y1){}

    }
    使用局部变量而非直接调用实参。

    打赏 评论
  • qq_39503635 2017-11-28 02:01

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

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

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

    打赏 评论
  • xlho2005 2017-12-09 14:35

    spring+springmvc+mybatis整合连接不上数据库

    打赏 评论
  • qq_36132368 2017-12-11 20:38

    你这样肯定是栈溢出了。之前也遇到过类似的情况, 因为编译器对栈的大小是有限制的,直接把BigInteger作为参数传递会导致溢出。确实内存还有优化的空间,但是这个程序的内存还远不到溢出,只是因为传参的时候栈溢出了。可以尝试用指针来传参

    打赏 评论
  • why_not_ 2018-01-31 03:49

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

    打赏 评论
  • paomianhuotui 2018-02-25 11:15

    代码不全(如:没有给出定义,其中Compare(P.x)就不清楚其具体含义呀),建议先代码尽量完整地发出来。才可以帮忙本地看下

    打赏 评论
  • BU凡 2018-03-28 08:35

    “代码编译连接都ok,运行半天最后报错 ,就是调用 计算数乘nP的函数Point_Multiply 时就卡住了,单步跟踪到这就执行不下去了。”
    你的编译运行都OK,那就应该考虑你的电脑配置问题,你的程序是在进行高速计算,运行程序时查看下运行内存爆没爆,是不是电脑卡死。你也可以换台高配置电脑试一下运行程序。

    打赏 评论
  • BMKB 2018-05-05 06:46

    对于单个数值的计算,np.sin的返回值类型和math.sin的不同,math.sin返回的是Python的标准float类型,而np.sin则返回一个float64类型。注意类型不同导致内存溢出

    打赏 评论
  • qq_42385073 2018-06-07 12:05

    大致看了一下,应该是内存溢出

    打赏 评论
  • 陆人葭 2018-07-17 02:52

    运行后报的是什么错误?
    栈溢出:一般是局部变量占用内存过多,导致使用的栈空间过多导致程序运行出现问题,解决方式是修改使用内存较多的局部变量使用堆内存,即通过new来分配内存;
    堆内存不足:使用new申请的内存太多,导致内存分配失败,可在new之后进行异常捕获判断内存是否申请成功;内存不足需要检查是否使用new之后没有使用delete回收内存,或者重新合理的设计程序。

    打赏 评论
  • 攻城狮加油 2018-07-19 11:39

    应该是内纯泄漏了吧

    打赏 评论

相关推荐 更多相似问题