-2

I'm having a problem allocating the char array in my get_company_info() function and am having seg faults in the get_employees function. I've played with couts in the functions and can't figure out what I'm doing wrong, only junk prints int main() for the name array; which is where data must be printed (don't ask why), but when printing in the function I've gotten the company name to print when I place it AFTER strncpy_s for some reason, but cannot get it to copy to the pointer database for some reason

I really need help quickly (within the next couple hours) and don't know what to do, thanks for your feedback.

... 
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;

//**********************************************************************
//*                         Symbolic Constants                         *
//**********************************************************************
#define COMPANY_ALLOC_ERR            1       //
#define EMPLOYEE_ALLOC_ERR           3       //
#define MAX_NAME_LENGTH              80      // Maximum length of the company name
#define NAME_ALLOC_ERR               2       //

//**********************************************************************
//*                         Program Structures                         *
//**********************************************************************
// Database record of company information
struct company_info
{
    const char  *p_company_name;   //
    float bonus_year;        //
    int   years_worked,      //
    employee_quantity; //
};

//**********************************************************************
//*                           Program Classes                          *
//**********************************************************************
// Database record of company employee bonuses
class employee_records
{
    int   id,            //
    service_years, //
    year_hired;    //
    float bonus;         //
public:
    // Set the data members
    void set_id            (int   i){id = i;               }
    void set_service_years (int   s){service_years = s;    }
    void set_year_hired    (int   y){year_hired = y;       }
    void set_bonus         (float b){bonus = b;}

    // Get the data members
    int   get_id           ()       {return id;            }
    int   get_service_years()       {return service_years; }
    int   get_year_hired   ()       {return year_hired;    }
    float get_bonus        ()       {return bonus;         }

    // Destructor, delete the employee bonus records database
    ~employee_records();
};

//**********************************************************************
//*      Delete the bonus record and print the destructor message      *
//**********************************************************************
employee_records :: ~employee_records()
{
    cout << "Destructor executing ...";
}

//**********************************************************************
//*                        Function Prototypes                         *
//**********************************************************************
void print_instructions              ();
// Print the program instructions
struct company_info *get_company_info();
//
employee_records get_employees       (struct company_info new_company_info);
//
void print_employees                 (employee_records *p_employee_records, int employee_quantity,
                                      const char *p_order_sort);
//
void sort_database                   (int employee_quantity,
                                      employee_records *p_employee_start);
//
void fatal_error                     (int error_number, const char *p_company_name,
                                      const char *p_function_name);
//
//**********************************************************************
//*                           Main Function                            *
//**********************************************************************
int main()
{
    struct company_info     *p_company_info;
    employee_records *p_employee_records;

    // Print the program heading and instructions
    print_instructions   ();

    // Get and print the company information
    p_company_info = get_company_info ();
    cout << "\n\nCompany name:        " << p_company_info->p_company_name;
    cout <<   "\nYear of the bonuses: " << p_company_info->years_worked;
    cout <<   "\nNumber of employees: " << p_company_info->employee_quantity;
    cout <<   "\nBonus per year:      " << p_company_info->bonus_year;

    // Get and print the unsorted employee bonus records database
    *p_employee_records = get_employees(*p_company_info);
    print_employees                    (p_employee_records,
                                        p_company_info->employee_quantity,
                                        "IN UNSORTED ORDER:");

    // Get and print the sorted employee bonus records database
    sort_database                     (p_company_info->employee_quantity,
                                       p_employee_records);
    print_employees                   (p_employee_records,
                                       p_company_info->employee_quantity,
                                       "SORTED BY YEAR HIRED:");

    // Release memory allocated for database of employee bonus records
    delete []p_employee_records;
    delete []p_company_info->p_company_name;
    delete   p_company_info;

    // Say goodbye and terminate the program
    cout <<       "\n\n\nThanks for processing employee bonuses today ;)";
    cout << "\n\n\n\n\n\n";
    return 0;
}

//**********************************************************************
//*                  Print the program instructions                    *
//**********************************************************************
void print_instructions()
{
    cout << "\n       ========================================================";
    cout << "\nThis program asks for information about your company and";
    cout << "\nabout each employee. It then calculates the bonus amount";
    cout << "\nowed each employee based on the number of service years.";
    return;
}

//**********************************************************************
//*                                     *
//**********************************************************************
struct company_info *get_company_info()
{
    char   company_name[MAX_NAME_LENGTH + 1]; //
    struct company_info *p_company_info;      //

    // Allocate the company information
    try
    {
        p_company_info = new company_info;
    }
    catch (bad_alloc xa)
    {
        fatal_error(COMPANY_ALLOC_ERR, p_company_info->p_company_name, "get_company_info");
    }

    // Allocate and get the company name

    try
    {
        p_company_info->p_company_name = new char [strlen(company_name)+1];
    }
    catch (bad_alloc xa)
    {
        fatal_error(NAME_ALLOC_ERR, p_company_info->p_company_name, "get_company_info");
    }
    cout << "\nEnter the name of your company here (no spaces): ";
    cin  >> company_name;
    strcpy_s(company_name, strlen(p_company_info->p_company_name) + 1, p_company_info->p_company_name);


    cout << company_name;
    cout << p_company_info->p_company_name;

    // Get the number of employees
    do
    {
        cout << "\nEnter your number of employees (1 or more): ";
        cin  >> p_company_info->employee_quantity;
    } while(p_company_info->employee_quantity < 1);

    // Get the year of the bonuses
    cout <<      "Enter the year in which the bonuses are given (YYYY): ";
    cin  >> p_company_info->years_worked;

    // Get the yearly bonus
    cout <<      "Give the yearly bonus amount per employee (in dollars): ";
    cin  >> p_company_info->bonus_year;

    //Return pointer to the structure
    return p_company_info;
}

//**********************************************************************
//*             *
//**********************************************************************
employee_records get_employees(struct company_info new_company_info)
{
    employee_records *p_start_employees  = NULL,
            *p_moving_employees = NULL;
    int              id                  = 1,
            service_years;

    // Allocate the employee bonus database
    try
    {
        p_start_employees = new employee_records;
    }
    catch(bad_alloc xa)
    {
        fatal_error(EMPLOYEE_ALLOC_ERR, new_company_info.p_company_name, "get_employees");
    }
    p_moving_employees = p_start_employees;

    // Get every employee's years of service
    do
    {
        // Loop processing valid number of service years
        do
        {
            cout << "\n\nEnter the number of service years of employee # " << id
                 <<      ".";
            cout <<   "\nEnter 0 (zero) if this employee does not exist:";
            cin  >> service_years;

            if (service_years < 0)
            {
                cout << "\n   The service years must be 0 or greater.";
                cout << "\n   Please reenter the number of service years.";
            }
        }while(service_years < 0);


        //
        if (service_years > 0)
        {
            p_moving_employees->set_id           (id);
            p_moving_employees->set_service_years(service_years);
            p_moving_employees->set_year_hired   ((int)(new_company_info.bonus_year - service_years));
            p_moving_employees->set_bonus        ((float)(new_company_info.years_worked * service_years));
            p_moving_employees++;
        }
        id++;

    }while((p_moving_employees - p_start_employees) < new_company_info.employee_quantity);

    // Return the pointer to the database of employee records
    return *p_start_employees;
}

//**********************************************************************
//*                                     *
//**********************************************************************
void print_employees(employee_records *p_employee_records, int employee_quantity,
                     const char *p_order_sort)
{
    employee_records *p_employee = NULL; // Points to the every employee record

    cout << "\n\nHere is the employee database, " << p_order_sort
         << ":";
    cout << "\n====================================================";
    cout << "\nEmployee Id   Service Years   Year Hired   Bonus Amt";
    cout << "\n-----------   -------------   ----------   ---------";

    for(p_employee = p_employee_records;
        (int)(p_employee - p_employee_records) < (employee_quantity -1); p_employee++)
    {
        cout << "\n     "     << p_employee->get_id           ()
             <<   "     ";
        cout <<   "         " << p_employee->get_service_years()
             <<   "      ";
        cout <<   "      "    << p_employee->get_year_hired   ()
             <<   "    ";
        cout <<   "    $"     << p_employee->get_bonus        ();
    }
    return;
}

//**********************************************************************
//*                                     *
//**********************************************************************
void sort_database(int employee_quantity, employee_records *p_employee_start)
{
    employee_records *p_employee_moving  = NULL, //
    temporary_employees;//
    int              sort_counter;               //

    for(sort_counter = 1; (sort_counter < employee_quantity); sort_counter++)
    {
        for(p_employee_moving = p_employee_start;
            (int)(p_employee_moving - p_employee_start) <
            (employee_quantity - sort_counter);)
        {
            if(p_employee_moving->get_service_years       () <
               (p_employee_moving + 1) -> get_service_years() )
            {
                temporary_employees      = *p_employee_moving;
                *p_employee_moving       = *(p_employee_moving + 1);
                *(p_employee_moving + 1) = temporary_employees;
            }

Thank you

Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
Eddy2022
  • 1
  • 1
  • 3
    You may want to read this: [Under what circumstances may I add "urgent" or other similar phrases to my question, in order to obtain faster answers?](https://meta.stackoverflow.com/q/326569/12149471) – Andreas Wenzel Apr 12 '22 at 10:04
  • Have you tried running your code line by line in a debugger while monitoring the values of all variables, in order to determine at which point your program stops behaving as intended? If you did not try this, then you may want to read this: [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/q/25385173/12149471) This should at least tell you in exactly which line the segfault is occurring. – Andreas Wenzel Apr 12 '22 at 10:17
  • Questions seeking debugging help should generally provide a [mre] of the problem, which includes the exact input required to reproduce the issue. – Andreas Wenzel Apr 12 '22 at 10:18
  • Your posted code does not compile. It seems to be incomplete. The function `sort_database` seems to be cut off. There seem to be at least 3 missing closing braces `}`. Please post a [mre]. – Andreas Wenzel Apr 12 '22 at 10:26
  • The strcy line should be ,strcpy_s(p_company_info->p_company_name , strlen(company_name) + 1, company_name); , but I get an Severity Code Description Project File Line Suppression State Error C2664 'errno_t strcpy_s(char *,rsize_t,const char *)': cannot convert argument 1 from 'const char *' to 'char *' Program06 C:\Users\eccma\source\repos\Program06\Program06\Program06.cpp 167 – Eddy2022 Apr 12 '22 at 12:07
  • Why did you specify that `p_company_name` is of type `const char *` in your definition of `struct company_info`? That error will probably disappear if you change it to `char *` (i.e. remove the `const`). – Andreas Wenzel Apr 12 '22 at 12:15
  • You are right, just saw it. Thank you – Eddy2022 Apr 12 '22 at 13:11
  • 2
    Please don't vandalize your question. If you are doing this in order to conceal academic dishonesty, then you may want to read this: [I've rethought my question about a homework assignment—why can't I get it deleted?](https://meta.stackoverflow.com/q/403802/12149471) – Andreas Wenzel Apr 13 '22 at 00:24
  • @wohlstad: I have now restored the original question. – Andreas Wenzel Apr 13 '22 at 05:25

1 Answers1

0

Your program is invoking undefined behavior.

In the function get_company_info, you are calling strlen(company_name). The function strlen requires its argument to be a pointer to a valid string, i.e. a pointer to a sequence of characters terminated by a null character. However, at that point in your program, the content of company_name is indeterminate, because you did not initialize it.

You probably want to move that line after the line

cin  >> company_name;

so that company_name will contain a valid string when you call strlen on it. It does not make sense to call strlen on a pointer that does not point to a valid string.

Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
  • strcpy_s(p_company_info->p_company_name , strlen(company_name) + 1, company_name); – Eddy2022 Apr 12 '22 at 12:03
  • @Eddy2022: In my answer, I was referring to this line: `p_company_info->p_company_name = new char [strlen(company_name)+1]` – Andreas Wenzel Apr 12 '22 at 12:06
  • But having issues with strcpy_s(p_company_info->p_company_name , strlen(company_name) + 1, company_name); the company name needs to be copied into p_commpany_info – Eddy2022 Apr 12 '22 at 12:19
  • Severity Code Description Project File Line Suppression State Error C2664 'errno_t strcpy_s(char *,rsize_t,const char *)': cannot convert argument 1 from 'const char *' to 'char *' Program06 C:\Users\eccma\source\repos\Program06\Program06\Program06.cpp 167 – Eddy2022 Apr 12 '22 at 12:19
  • getting that error – Eddy2022 Apr 12 '22 at 12:20
  • @Eddy2022: If that is the same error messge as in the comment that you posted in the comments section of your question, then you have already received my reply in that section. – Andreas Wenzel Apr 12 '22 at 12:23
  • I moved the cin to where you told me and that is where it should be. Trying now to solve the strcpy_c line – Eddy2022 Apr 12 '22 at 12:43
  • Just found the error, when the struct was declared , the string was a cont – Eddy2022 Apr 12 '22 at 12:51
  • I have update the code, On line *p_employee_records = get_employees(*p_company_info); I get an Exception thrown at 0x0077639C in p6.exe: 0xC0000005: Access violation writing location 0x00000000. – Eddy2022 Apr 12 '22 at 13:18
  • @Eddy2022: You are probably dereferencing a `NULL` pointer somewhere. I suggest that you run your program line by line in a [debugger](https://stackoverflow.com/q/25385173/12149471) while monitoring the values of all variables, to see at which point your program stops behaving as intended. – Andreas Wenzel Apr 12 '22 at 13:57