C ++入门练习1.20运行错误

时间:2016-02-10 15:12:02

标签: c++ visual-studio-2015

从C ++ Primer 5th Edition一书中练习1.20在我运行程序时抛出错误。我尝试在3台不同的计算机上运行该程序,结果相同。我一直在使用Visual Studio 2015作为我的IDE。我怀疑Visual Studio是罪魁祸首,但是我不太了解它自己搞清楚,而且我对搜索没有任何好运。谢谢!

错误消息如下:

  

Debug Assertion失败!

     

程序:C:\ Windows \ system32 \ MSVCP140D.dll文件:c:\ program files   (x86)\ microsoft visual studio 14.0 \ vc \ include \ xstring Line:1175

     

表达式:无效的空指针

以下是我的源代码:

#include <iostream>
#include "Sales_item.h"

    int main()
    {
        Sales_item nonzero = 0;
        while (std::cin >> nonzero)
            std::cout << nonzero;
        return 0;
    }

头文件&#34; Sales_item.h&#34;如下:

#ifndef SALESITEM_H
// we're here only if SALESITEM_H has not yet been defined 
#define SALESITEM_H

#include "Version_test.h" 

// Definition of Sales_item class and related functions goes here
#include <iostream>
#include <string>

class Sales_item {
// these declarations are explained section 7.2.1, p. 270 
// and in chapter 14, pages 557, 558, 561
friend std::istream& operator>>(std::istream&, Sales_item&);
friend std::ostream& operator<<(std::ostream&, const Sales_item&);
friend bool operator<(const Sales_item&, const Sales_item&);
friend bool 
operator==(const Sales_item&, const Sales_item&);
public:
    // constructors are explained in section 7.1.4, pages 262 - 265
    // default constructor needed to initialize members of built-in type
#if defined(IN_CLASS_INITS) && defined(DEFAULT_FCNS)
    Sales_item() = default;
#else
    Sales_item(): units_sold(0), revenue(0.0) { }
#endif
    Sales_item(const std::string &book):
              bookNo(book), units_sold(0), revenue(0.0) { }
    Sales_item(std::istream &is) { is >> *this; }
public:
    // operations on Sales_item objects
    // member binary operator: left-hand operand bound to implicit this pointer
    Sales_item& operator+=(const Sales_item&);

    // operations on Sales_item objects
    std::string isbn() const { return bookNo; }
    double avg_price() const;
// private members as before
private:
    std::string bookNo;      // implicitly initialized to the empty string
#ifdef IN_CLASS_INITS
    unsigned units_sold = 0; // explicitly initialized
    double revenue = 0.0;
#else
    unsigned units_sold;  
    double revenue;       
#endif
};

// used in chapter 10
inline
bool compareIsbn(const Sales_item &lhs, const Sales_item &rhs) 
{ return lhs.isbn() == rhs.isbn(); }

// nonmember binary operator: must declare a parameter for each operand
Sales_item operator+(const Sales_item&, const Sales_item&);

inline bool 
operator==(const Sales_item &lhs, const Sales_item &rhs)
{
    // must be made a friend of Sales_item
    return lhs.units_sold == rhs.units_sold &&
           lhs.revenue == rhs.revenue &&
           lhs.isbn() == rhs.isbn();
}

inline bool 
operator!=(const Sales_item &lhs, const Sales_item &rhs)
{
    return !(lhs == rhs); // != defined in terms of operator==
}

// assumes that both objects refer to the same ISBN
Sales_item& Sales_item::operator+=(const Sales_item& rhs) 
{
    units_sold += rhs.units_sold; 
    revenue += rhs.revenue; 
    return *this;
}

// assumes that both objects refer to the same ISBN
Sales_item 
operator+(const Sales_item& lhs, const Sales_item& rhs) 
{
    Sales_item ret(lhs);  // copy (|lhs|) into a local object that we'll return
    ret += rhs;           // add in the contents of (|rhs|) 
    return ret;           // return (|ret|) by value
}

std::istream& 
operator>>(std::istream& in, Sales_item& s)
{
    double price;
    in >> s.bookNo >> s.units_sold >> price;
    // check that the inputs succeeded
    if (in)
        s.revenue = s.units_sold * price;
    else 
        s = Sales_item();  // input failed: reset object to default state
    return in;
}

std::ostream& 
operator<<(std::ostream& out, const Sales_item& s)
{
    out << s.isbn() << " " << s.units_sold << " "
        << s.revenue << " " << s.avg_price();
    return out;
}

inline bool operator<(const Sales_item &, const Sales_item &)
{
    return false;
}

double Sales_item::avg_price() const
{
    if (units_sold) 
        return revenue/units_sold; 
    else 
        return 0;
}
#endif

它引用另一个名为&#34; Version_test.h&#34;。

的头文件
#ifndef VERSION_TEST_H
#define VERSION_TEST_H

/* As of the first printing of C++ Primer, 5th Edition (July 2012), 
 * the Microsoft Complier did not yet support a number of C++ 11 features.  
 *
 * The code we distribute contains both normal C++ code and 
 * workarounds for missing features.  We use a series of CPP variables to
 * determine whether a given features is implemented in a given release
 * of the MS compiler.  The base version we used to test the code in the book
 * is Compiler Version 17.00.50522.1 for x86.
 *
 * When new releases are available we will update this file which will
 * #define the features implmented in that release.
*/

#if _MSC_FULL_VER == 170050522 || _MSC_FULL_VER == 170050727 
// base version, future releases will #define those features as they are
// implemented by Microsoft

/* Code in this delivery use the following variables to control compilation

   Variable tests           C++ 11 Feature 
CONSTEXPR_VARS            constexpr variables
CONSTEXPR_FCNS            constexpr functions
CONSTEXPR_CTORS           constexpr constructors and other member functions
DEFAULT_FCNS              = default 
DELETED_FCNS              = delete  
FUNC_CPP                  __func__ local static
FUNCTION_PTRMEM           function template with pointer to member function
IN_CLASS_INITS            in class initializers 
INITIALIZER_LIST          library initializer_list<T> template
LIST_INIT                 list initialization of ordinary variables
LROUND                    lround function in cmath
NOEXCEPT                  noexcept specifier and noexcept operator
SIZEOF_MEMBER             sizeof class_name::member_name
TEMPLATE_FCN_DEFAULT_ARGS default template arguments for function templates
TYPE_ALIAS_DECLS          type alias declarations
UNION_CLASS_MEMS          unions members that have constructors or copy control
VARIADICS                 variadic templates
*/
#endif  // ends compiler version check

#ifndef LROUND
inline long lround(double d)
{
    return (d >= 0) ?  long(d + 0.5) : long(d - 0.5);
}
#endif

#endif  // ends header guard

1 个答案:

答案 0 :(得分:2)

您的问题是由此行引起的:

Sales_item nonzero = 0;

因为这个构造函数:

Sales_item(const std::string &book)
使用

因为0可以表示空char*,而std::string可以从char*构建。

出现问题是因为从空指针构造std::string无效。

该行应为

Sales_item nonzero;

(顺便说一下,工具出错的情况非常罕见。最可能的罪魁祸首总是你自己编写的代码。)