1

我向大家展示我正在为我的大学编程课程开发的一个程序。在它完全满足我的作业要求之前我还有一些路要走,但是我已经得到了一个没有错误的程序的基本草稿(据说)并且它似乎可以运行......但是它突然把我踢进了 Xcode 的调试器并给出我:

Thread 1: EXC_BAD_ACCESS(code=2, address=0x7fff95c1e5f5)

这是命令行输出,直到它把我踢出去:

    -----------------------
    Quarterly_sales_taxator
    -----------------------


    How many company divisions will we be dealing with?  2


    Am I correct in assuming that there are 4 sales quarters?    yes



    Please enter the sales Company Division #1 brought in for Sales Quarter #1   20
    (lldb)

这是我的代码:

    //
    //  quarterly_sales_taxator.cpp
    //  Ch. 7 program #7
    //
    //  Created by John Doe on 11/27/12.
    //

    #include <iostream>
    #include <iomanip>
    #include <string>
    #include <sstream>
    #include <cctype>
    using namespace std;

    void read_company_divisions_and_sales_quarters(double **, int, int);
        //void write_company_divisions_and_sales_quarters_to_array(double **, int, int);    // This will be used later on to read data from a file.
    void display_quarterly_sales_array(double **, int, int);

    string temp;    // A global temporary placeholder variable; I use this several times.


    int main()
    {
        int COMPANY_DIVISIONS,
            SALES_QUARTERS = 4;

        double **quarterly_sales_form;


        cout << "\n\n-----------------------\nQuarterly_sales_taxator\n-----------------------\n\n";

        cout << "\nHow many company divisions will we be dealing with?  ";
        getline(cin, temp);
        stringstream(temp)>>COMPANY_DIVISIONS;

        while (COMPANY_DIVISIONS < 1 || isdigit(COMPANY_DIVISIONS == false))
        {
            cout << "\n\n------"
                 << "\nError:"
                 << "\n------"
                 << "\n\nYou have entered an invalid choice."
                 << "\nPlease type a number greater than zero.    ";

            getline(cin, temp);
            stringstream(temp)>>COMPANY_DIVISIONS;
        }

        cout << "\n\nAm I correct in assuming that there are 4 sales quarters?    ";
        getline(cin, temp);

                // Convert to uppercase.
            for (int count = 0; count < temp.length(); count ++)
            {
                temp[count] = toupper(temp[count]);
            }

            if (temp == "NO" || temp == "NOPE" || temp == "INCORRECT" || temp == "YOU ARE NOT" || temp == "YOU ARE INCORRECT" || temp == "NEGATIVE" || temp == "NEGATORY")
            {
                cout << "\nOk, then how many sales quarters are we dealing with?    ";
                getline(cin, temp);
                stringstream(temp)>>SALES_QUARTERS;
            }

        cout << endl << endl;

            // This sets up the 2d array.
        quarterly_sales_form = new double *[COMPANY_DIVISIONS];
        for (int count = 0; count < COMPANY_DIVISIONS; count ++)
        {   quarterly_sales_form[COMPANY_DIVISIONS] = new double [SALES_QUARTERS];  }

        read_company_divisions_and_sales_quarters(quarterly_sales_form, COMPANY_DIVISIONS, SALES_QUARTERS);
            //  write_company_divisions_and_sales_quarters_to_array(quarterly_sales_form, COMPANY_DIVISIONS, SALES_QUARTERS);   // I'll add this feature later.


        cout << "\n\nHere's what you entered:\n\n";
        display_quarterly_sales_array(quarterly_sales_form, COMPANY_DIVISIONS, SALES_QUARTERS);

            // Since we used a series of pointers, we need to free the allocated space back up.
        for (int count = 0; count < COMPANY_DIVISIONS; count ++)
        {   delete[] quarterly_sales_form[COMPANY_DIVISIONS];  }
        delete[] quarterly_sales_form;



        return 0;
    }


    /*############################################
     # read_company_divisions_and_sales_quarters #
     ############################################*/
    void read_company_divisions_and_sales_quarters(double **array, int DIVISIONS, int QUARTERS)
    {

            for (int count = 0; count < QUARTERS; count++)
            {

                for (int index = 0; index < DIVISIONS; index++)
                {
                    cout << "\nPlease enter the sales Company Division #" << count+1 << " brought in for Sales Quarter #" << index+1 << "   ";
                    getline(cin, temp);
                    stringstream(temp) >> array[count][index];
                }
            }
    }


    /*################################
     # display_quarterly_sales_array #
     #################################*/
    void display_quarterly_sales_array(double **array, int DIVISIONS, int QUARTERS)
    {
        for (int count = 0; count < DIVISIONS; count++)
        {
            cout << "\nCompany division #" << count+1 << ":\n";
            for (int index = 0; index < QUARTERS; index++)
            {    cout << array[count][index] << ", ";    }
        }

    }

可以请一些善良的灵魂告诉我我做错了什么吗?

4

2 回答 2

5
    {   quarterly_sales_form[COMPANY_DIVISIONS] = new double [SALES_QUARTERS];  }

在这一行中,COMPANY_DIVISIONS应该是count

于 2012-12-05T22:44:50.330 回答
2

除了Dan Hulme所说的,似乎这条线

stringstream(temp) >> array[count][index];

真的应该

std::istringstream(temp) >> std::skipws >> array[index][count];

除了使用std::istringstream而不是std::stringstream确保手头有一个左值(在读取的类型变得更有趣之前,这并不是严格需要的)之外,这还反转了索引:一遍又一遍地index运行。COMPANY_DIVISIONScountSALES_QUARTERS

当然,真正的问题是:谁分发这样的作业?指针操作和分配最好留给低级库编写者。这是 C++ 而不是 C:我们可以而且应该使用抽象。确保代码异常安全是一项重大挑战,教人们如何编写损坏的(例如异常不安全的)代码是没有意义的。

于 2012-12-05T22:53:05.003 回答