-2

The below code works perfectly with strings but with char it gives segmentation fault.

#include<iostream>
using namespace std;

class salary
{
public:
    int empno;
    float inctax;
    float netsal;
    int gross;
    short int age;
    char name[50];

    salary(){
        empno=0;
        gross=0;
        age=0;
        strcpy(name,'\0');
    }

    salary(int empn,int gros,short int ag,char nam[]){
        empno=empn;
        gross=gros;
        age=ag;
        strcpy(name,nam);
    }

    void calc(){
        inctax=0.0;
        if(gross>1000000)
            inctax=0.3*gross;
        else if(gross>=500000 && gross<=1000000)
            inctax=0.2*gross;
        else if(gross>=250000 && gross<500000)
            inctax=0.1*gross;
        else
            inctax=0.0;
        netsal=gross-inctax;
        cout<<"inctax"<<inctax;
        cout<<"net sal"<<netsal;
    }
};

int main(){
    salary *r=new salary();
    salary *r1=new salary(112,500000,21,"Arnab");
    r1->calc();
    return 0;
}
cf-
  • 8,598
  • 9
  • 36
  • 58

2 Answers2

3

I agree with vu1p3n0x's comment, the problem is in the default constructor.

strcpy(name, '\0'); // This is wrong!

strcpy() takes two char arrays as arguments, but a character itself was passed as the second argument in your code. The syntax of strcpy() is:

char * strcpy ( char * destination, const char * source );

In order to create null string using char arrays, you should probably use,

strcpy(name, "\0");
     /*or*/ 
name[0] = '\0';

More on copying string, Reference and tutorialspoint

Praveen Kishore
  • 436
  • 1
  • 3
  • 14
1

Your main problem is that your compiler isn't telling you about the obvious errors in the code. If you have correctly told it to report errors, then you perhaps need a better compiler. Here's the output I get when I compile:

g++ -std=c++14 -fPIC -g -Wall -Wextra -Wwrite-strings -Wno-parentheses     38113648.cpp   -o 38113648
38113648.cpp: In constructor ‘salary::salary()’:
38113648.cpp:18:25: error: ‘strcpy’ was not declared in this scope
         strcpy(name,'\0');
                         ^
38113648.cpp: In constructor ‘salary::salary(int, int, short int, char*)’:
38113648.cpp:25:24: error: ‘strcpy’ was not declared in this scope
         strcpy(name,nam);
                        ^
38113648.cpp: In function ‘int main()’:
38113648.cpp:46:48: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
     salary *r1=new salary(112,500000,21,"Arnab");
                                                ^
38113648.cpp:45:13: warning: unused variable ‘r’ [-Wunused-variable]
     salary *r=new salary();
             ^

When I add

#include <cstring>

and change the constructor to take char const[], I get

g++ -std=c++14 -fPIC -g -Wall -Wextra -Wwrite-strings -Wno-parentheses     38113648.cpp   -o 38113648
38113648.cpp: In constructor ‘salary::salary()’:
38113648.cpp:19:25: warning: null argument where non-null required (argument 2) [-Wnonnull]
         strcpy(name,'\0');
                     ^

Obviously you meant that to be "\0". Better still, provide an initializer:

salary()
    : empno{0},
      gross{0},
      age{0},
      name{0}
{
}

salary(int empno, int gross, short int age, char const name[])
    : empno{empno},
      gross{gross},
      age{age}
{
    strcpy(this->name, name);
}

(I've also given the formal parameters more meaningful names, as this often forms the documentation of the constructor).

Adding -Weffc++ may also be worthwhile - in this case it warns that you don't initialize inctax or netsal in the constructors. If you're happy to have part-initialized objects, you'll obviously need to use Valgrind to check that these values are indeed set before they are used, because it can't be determined statically.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103