繁体   English   中英

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

[英]C++ Primer Exercise 1.20 Run Error

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

错误消息如下:

调试断言失败!

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

表达式:无效的空指针

以下是我的源代码:

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

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

头文件“ Sales_item.h”如下:

#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

它引用了另一个名为“ Version_test.h”的头文件。

#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

您的问题是由以下行引起的:

Sales_item nonzero = 0;

由于这个构造函数:

Sales_item(const std::string &book)

之所以使用它,是因为0可以表示一个空char* ,并且std::string可以从char*构造。

发生您的问题是因为从空指针构造std::string是无效的。

该行应该是

Sales_item nonzero;

(顺便说一句,这些工具有过错的可能性非常少。最可能的罪魁祸首总是您自己编写的代码。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM