| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1312 人关注过本帖
标题:求助大佬!纠正bug
只看楼主 加入收藏
复旦
Rank: 3Rank: 3
等 级:论坛游侠
威 望:2
帖 子:81
专家分:124
注 册:2018-10-29
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:8 
求助大佬!纠正bug
设计了一个矢量类。运行后,构造函数里声明element后element的地址是0xcccccccc。 然后出错无法读取该内存地址。
这个错误有时候还会在拷贝构造函数里面出现。 不知道为什么拷贝构造函数被调用了。   请大佬纠正问题。

#include "stdafx.h"
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cstdarg>

typedef class myvector
{
public:
    myvector()    //0参数构造函数
    {
        element=new double[3];
        for (int i=0;i<3;i++)
            element[i]=0;
    }
    myvector(int count,...)    //N参数构造函数
    {
        N=count;
        element=new double[N];              //这里出错   element地址为Oxccccccc//
        va_list ap;
        va_start (ap,count);
        for (int i=0;i<N;i++)
        {
            element[i]=va_arg(ap,double);
        }
        va_end(ap);
    }
    myvector(const myvector& n)   //拷贝构造函数
    {
        N=n.N;
        if (element !=NULL)
            delete[] element;                         //有时候这里出错。 同样element地址是0xcccccccc。 显示无法读取该内存地址//
        element=new double[N];
        for (int i=0;i<N;i++)
            element[i]=n.element[i];
    }
    ~myvector()    //析构函数
    {
        delete[] element;
    }
    myvector operator + (const myvector& other)   //重载+操作符
    {
        myvector result;
        for (int i=0;i<N;i++)
            result.element[i]=element[i]+other.element[i];
        return result;
    }

    myvector operator - (const myvector& other)   //重载-操作符
    {
        myvector result;
        for (int i=0;i<N;i++)
            result.element[i]=element[i]-other.element[i];
        return result;
    }

    myvector operator * (int n)   //重载*操作符(矢量*数)
    {
        myvector result;
        for (int i=0;i<N;i++)
            result.element[i]=element[i]*n;
        return result;
    }

    void print()     //输出函数
    {
        printf ("(");
        for (int i=0;i<N;i++)
            printf ("%.3f ",element[i]);
        printf (")\n");
    }

    void SetDim(int i)     //维度设置函数
    {
        N=i;
        for (int j=0;j<N;j++)
            element[j]=0;
    }

public:
    int N;
    double * element;
}Vector;

int main()
{
    int i;
    Vector a(2,5.6,4.5),b(2,4.5,7.4);
    Vector c;
    c=a+b;
    a.print();
    b.print();
    c.print();
    scanf ("%d",&i);
    return 0;
}
搜索更多相关主题的帖子: element for int i++ result 
2018-10-30 13:52
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9007
专家分:53942
注 册:2011-1-18
收藏
得分:17 
错误挺多的

    myvector()    //0参数构造函数
    {
        element=new double[3];
        for (int i=0;i<3;i++)
            element[i]=0;
    }
中未给 N 赋值,而 myvector operator + (const myvector& other) 等函数中在拷贝构造时又用到了它。

    myvector(const myvector& n)   //拷贝构造函数
    {
        N=n.N;
        if (element !=NULL)
            delete[] element;                         //有时候这里出错。 同样element地址是0xcccccccc。 显示无法读取该内存地址//
        element=new double[N];
        for (int i=0;i<N;i++)
            element[i]=n.element[i];
    }
中 element 尚未赋值,也就不可以 if (element !=NULL),当然也不可以 delete[] element;

既然有了拷贝构造,却缺少operator=操作,这其实就是你说“element地址是0xcccccccc”的原因

myvector operator + (const myvector& other) 中根本没考虑 result.N 和 this->N 和 other.N 是否相等
myvector operator - (const myvector& other) 同上

其它错误和外行的写法就不多说了,最好重写code
2018-10-30 14:56
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9007
专家分:53942
注 册:2011-1-18
收藏
得分:0 
不是有 std::valarray 吗,难道不符合你的要求?
随手瞎写的,仅供参考
程序代码:
#include <ostream>
#include <cstdarg>
#include <cassert>

class Vector
{
public:
    Vector() : size_(), elements_() // 按C++标准最好加上 noexcept,但一看你的代码“#include "stdafx.h"”,算了吧
    {
    }

    Vector( size_t size, ... ) try : size_(size), elements_(new double[size]) // 这玩意儿吓我一跳,我只会 std::initializer_list
    {
        va_list ap;
        va_start( ap, size );
        for( size_t i=0; i!=size_; ++i )
            elements_[i] = va_arg( ap, double );
        va_end( ap );
    }
    catch( ... ) { throw; }

    Vector( const Vector& other ) try: size_(other.size_), elements_(new double[other.size_])
    {
        for( size_t i=0; i!=size_; ++i )
            elements_[i] = other.elements_[i];
    }
    catch( ... ) { throw; }

    Vector& operator=( const Vector& other )
    {
        if( this != &other )
        {
            double* p;
            try {
                p = new double[other.size_];
            }
            catch( ... ) {
                throw;
            }

            size_ = other.size_;
            delete[] elements_;
            elements_ = p;

            for( size_t i=0; i!=size_; ++i )
                elements_[i] = other.elements_[i];
        }
        return *this;
    }

    // 这里应该加上 Vector( Vector&& other ) 和 Vector& operator=( Vector&& other )。懒得写了

    ~Vector()
    {
        delete[] elements_;
    }

    Vector operator+( const Vector& other ) const
    {
        assert( size_ == other.size_ ); // 为了统一,最好throw异常
        Vector result = *this;
        for( size_t i=0; i!=size_; ++i )
            elements_[i] += other.elements_[i];
        return result;
    }

    Vector operator-( const Vector& other ) const
    {
        assert( size_ == other.size_ );
        Vector result = *this;
        for( size_t i=0; i!=size_; ++i )
            elements_[i] -= other.elements_[i];
        return result;
    }

    Vector operator*( double value ) const
    {
        Vector result = *this;
        for( size_t i=0; i!=size_; ++i )
            elements_[i] *= value;
        return result;
    }

    void resize( size_t size )
    {
        if( size <= size_ )
            size_ = size;
        else
        {
            double* p;
            try {
                p = new double[size];
            }
            catch( ... ) {
                throw;
            }

            for( size_t i=0; i!=size_; ++i )
                p[i] = elements_[i];
            for( size_t i=size_; i!=size; ++i )
                p[i] = 0;

            delete[] elements_;
            elements_ = p;
            size_ = size;
        }
    }

    friend std::ostream& operator<<( std::ostream& os, const Vector& vec )
    {
        os << "( ";
        for( size_t i=0; i!=vec.size_; ++i )
            os << vec.elements_[i] << ' ';
        os << ')';
        return os;
    }

private:
    size_t size_;
    double* elements_;
};

#include <iostream>
#include <iomanip>
using namespace std;

int main( void )
{
    Vector a( 2, 5.6, 4.5 );
    Vector b( 2, 4.5, 7.4 );
    Vector c = a + b;

    cout << fixed << setprecision(3)
         << a << '\n'
         << b << '\n'
         << c << endl;

    return 0;
}

2018-10-30 15:36
复旦
Rank: 3Rank: 3
等 级:论坛游侠
威 望:2
帖 子:81
专家分:124
注 册:2018-10-29
收藏
得分:0 
非常感谢rjsp大佬的错误纠正!
可以正常运行了。
还有,可以说明std命名空间的概念和 =操作符重载后写的“这里应该加上 Vector( Vector&& other ) 和 Vector& operator=( Vector&& other )”
这句话的含义吗?
2018-10-30 19:48
复旦
Rank: 3Rank: 3
等 级:论坛游侠
威 望:2
帖 子:81
专家分:124
注 册:2018-10-29
收藏
得分:0 
回复 3楼 rjsp
如果想构造函数实参里只允许输入数值,不允许bool,char类型的话,要怎么设计throw, try, catch?
还有,目前的代码实行 Vector (3,2,5,6)的话, 因为2,5,6是int型所以构造函数里不执行正确的赋值。这个要怎么办呢?

2018-10-30 20:45
Jonny0201
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:52
帖 子:488
专家分:2603
注 册:2016-11-7
收藏
得分:3 
Vector && 是 C++ 11 引入的移动语意, 对应的就是移动构造函数和移动赋值运算符
对于构造函数只允许数值, 可以使用 typeid 进行判断
if(typeid(value) == typeid(bool) or typeid(value) == typeid(char)) {
    throw std::runtime_error("Type error");
}

最好直接是编译期进行萃取, 然后直接 static_assert
2018-10-30 20:57
复旦
Rank: 3Rank: 3
等 级:论坛游侠
威 望:2
帖 子:81
专家分:124
注 册:2018-10-29
收藏
得分:0 
Jonney大佬,我不太会写处理异常代码。
麻烦您可以写个完整的吗?
对任何一个函数,写一个完整异常处理代码就行。
谢谢!
2018-10-30 23:08
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9007
专家分:53942
注 册:2011-1-18
收藏
得分:0 
回复 5楼 复旦
完整、且标准 的所有代码如下。
先看 main 函数,了解一下 Vector 是怎么使用的。

程序代码:
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>

class Vector
{
public:
    Vector() noexcept : elements_()
    {
    }
    ~Vector() = default;
    Vector( const Vector& other ) = default;
    Vector( Vector&& other ) noexcept = default;
    explicit Vector( size_t count, double value=double() ) : elements_(count,value)
    {
    }
    Vector( std::initializer_list<double> init ) : elements_(init)
    {
    }

    Vector& operator=( const Vector& other ) = default;
    Vector& operator=( Vector&& other ) noexcept = default;
    Vector& operator=( std::initializer_list<double> init )
    {
        elements_ = init;
        return *this;
    }

    void resize( size_t count, double value=double() )
    {
        elements_.resize( count, value );
    }

    template<class FUN>
    Vector operator_( FUN&& fun, const Vector& other, double defval ) const
    {
        Vector result( std::max(elements_.size(),other.elements_.size()) );
        for( size_t i=0; i!=result.elements_.size(); ++i )
        {
            double a = i<elements_.size() ? elements_[i] : defval;
            double b = i<other.elements_.size() ? other.elements_[i] : defval;
            result.elements_[i] = fun( a, b );
        }
        return result;
    }

    Vector operator+( const Vector& other ) const
    {
        return operator_( std::plus<double>(), other, 0.0 );
    }

    Vector operator-( const Vector& other ) const
    {
        return operator_( std::minus<double>(), other, 0.0 );
    }

    Vector operator*( double value ) const
    {
        Vector result = *this;
        for( auto& v : result.elements_ )
            v *= value;
        return result;
    }

    friend Vector operator*( double value, const Vector& rhs )
    {
        return rhs * value;
    }

    friend std::ostream& operator<<( std::ostream& os, const Vector& vec )
    {
        os << "( ";
        for( auto& v : vec.elements_ )
            os << v << ' ';
        os << ')';
        return os;
    }

private:
    std::vector<double> elements_;
};

#include <iomanip>
using namespace std;

int main( void )
{
    Vector a; // 空集合
    cout << a << endl; // {}

    Vector b( 3 ); // 3个元素的集合,每个元素缺省值都为0.0
    cout << b << endl; // { 0, 0, 0 }

    Vector c( 3, 1.2 ); // 3个元素的集合,每个元素值都为1.2
    cout << c << endl; // { 1.2, 1.2, 1.2 }

    Vector d = { 1.2, 2.3, 3.4 }; // 3个元素的集合,元素值在列表中
    cout << d << endl; // { 1.2, 2.3, 3.4 }

    d = c;
    cout << d << endl; // { 1.2, 1.2, 1.2 }

    d = { 0, 1, 2, 3, 4, 5 };
    cout << d << endl; // { 0, 1, 2, 3, 4, 5 }

    cout << c+d << endl; // { 1.2, 1.2, 1.2 } + { 0, 1, 2, 3, 4, 5 } = { 1.2, 2.2, 3.2, 3, 4, 5 }

    cout << c-d << endl; // { 1.2, 1.2, 1.2 } - { 0, 1, 2, 3, 4, 5 } = { 1.2, 0.2, -0.8, -3, -4, -5 }

    cout << c*2 << endl;  // { 1.2, 1.2, 1.2 } * 2 = { 2.4, 2.4, 2.4 }

    cout << 2*c << endl;  // 2 * { 1.2, 1.2, 1.2 } = { 2.4, 2.4, 2.4 }

    cout << fixed << setprecision(3) // 以固定3位小数的方式显示浮点数
        << a << '\n'
        << b << '\n'
        << c << endl;

    return 0;
}

2018-10-31 10:01
复旦
Rank: 3Rank: 3
等 级:论坛游侠
威 望:2
帖 子:81
专家分:124
注 册:2018-10-29
收藏
得分:0 
非常感谢。我看一段时间,有问题再来问您。
2018-10-31 13:15
快速回复:求助大佬!纠正bug
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.022115 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved