473,394 Members | 1,693 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

Weird behaviour of compiler

I was working on a project in c++,which involved managing accounts.Here is an extract of source code of project

1.logging in

Expand|Select|Wrap|Line Numbers
  1. user user::login(short int pur)
  2. {
  3.     clrscr();
  4.     fstream f("users.dat",ios::in|ios::out|ios::binary);
  5.     user u[10];
  6.     int i=0;
  7.     while(f.read((char*)&u[i],sizeof(user)))
  8.         i++;
  9.     f.close();
  10.     cout<<"Enter user name\n";
  11.     char n[30];
  12.     gets(n);
  13.     int pos=search(u,n,i);
  14.     int chk=0;
  15.     if(pos==-1)
  16.     {
  17.         cout<<"Sorry user not found\n";
  18.         return fail();
  19.     }
  20.     cout<<"Enter password\n";
  21.     gets(n);
  22.     int ver=verify_password(u[pos],n);
  23.     if(ver==0)
  24.     {
  25.         if(pur==0)
  26.         {
  27.             cout<<"Access granted\n";
  28.             getch();
  29.         }
  30.         return u[pos];
  31.     }
  32.     cout<<"Incorrect password\n";
  33.     return fail();
  34. }
  35.  
2.Changing password

Expand|Select|Wrap|Line Numbers
  1. user user::change_password()
  2. {
  3.     user u;
  4.     u=login();
  5.     .
  6.     .          //The problem occurs within this.Hence,
  7.     .          //I don't think the rest of the code
  8.     .          //is required
  9.     .
  10.  
You don't have to read the whole of the first code, because the problem occurs within the first few lines.As you might have guessed, user is the name of a class.

Now, here is the most weird problem I have ever faced-

1.If I directly call the directly,login() function it executes properly.OK very good.

2.If I call the login() function from change_password() function(by running it normally using ctrl+F9) it shows divide error exception.OK maybe something to do with the arguments passed.

3.If I execute the same function, through the same change_password() function, step by step,it shows General Protection Fault(not divide error exception)!!!

That's not all!!When I execute the change_password() function normally ,it fails to clear the screen itself ( the very first statement).However if I execute the same function step by step it get struck just before array of object is initialised( 3rd statement). Like I already mentioned if I directly call the login() function it does not show any error.Hence it has gone nothing to do with the array size.

Someone please explain this weird behaviour to me and correct my code.I appreciate an early response.
Dec 30 '15 #1
13 1374
weaknessforcats
9,208 Expert Mod 8TB
The first thing I see is that login() is supposed to return a user but there are places where it's returning fail(). That fail appears to trigger a user constructor so login() returns a corrupt object.

As a rule in C++ functions should receive reference arguments so there's nothing to return. The function return value would then be available for pass/fail values.
Dec 30 '15 #2
Forget about returning values.It encounters the exception even before the declaration of object takes place.Moreover if what you told is right, then when I directly call login() function, it shouldn't work.But in reality it does work properly.
Dec 31 '15 #3
weaknessforcats
9,208 Expert Mod 8TB
What does user::operator= look like? You might post the user class code.

What exception?

Also, when you say it works when you call login() directly do you mean:

Expand|Select|Wrap|Line Numbers
  1. int main()
  2. {
  3.    login();
  4. }
or do you mean:

Expand|Select|Wrap|Line Numbers
  1. int main()
  2. {
  3. user u;
  4. u=login();
  5. }
I do say again that the return from fail() is not a valid user constructor argument. You need to have a user& as an argument to user::change_password. That way you can use the return from login() for fail() as you are currently doing.

Note also that the return from user::change_password is a user object and the only one around is a local object which I presume is returned so that would trigger a copy constructor call to get from the local user object to the returned user object. I would like to see the user copy constructor.

Where is the password? Is the object used by user::change_password the this object? If so, then why have a user object in this code when the this is all you need.

Hopefully your code post will clear this up
Dec 31 '15 #4
I haven't defined an operator like '=' in my class.Instead,I have used the operator '=' which the compiler itself provides. I have done so,because there are too many members in the class and none of these require a change in value when an object is initialized to another object.Hence,I would be wasting ultra lot of time for typing this, but would gain nothing.But anyway, since you asked for the class definition of 'user', here it is-

Expand|Select|Wrap|Line Numbers
  1. class user
  2. {
  3.     char name[30],pass[30];
  4.     unsigned int pts,n_pts;
  5.     short int dif,a_dif,prev_mis,no_wins,cons_mis,cons_switch,tot_wins,loss;
  6.     float wrong;
  7.     public:user(char n[]="\0\0\0",char p[]="\0\0\0")
  8.     {
  9.         strcpy(name,n);
  10.         strcpy(pass,p);
  11.         pts=n_pts=dif=a_dif=prev_mis=no_wins=cons_mis=cons_switch=cons_switch=tot_wins=loss=0;
  12.         wrong=0;
  13.     }
  14.  
  15.     /*The code after this
  16.     has all member functions
  17.     declared within it*/
  18.     .
  19.     .
  20.     .
  21.  
  22. };
  23.  
When I said "calling the login() function directly" ,I meant the second code, which you gave.

The function fail() is not a constructor.It is a user-defined(non-member) function, which is defined this way-

Expand|Select|Wrap|Line Numbers
  1. inline user fail()
  2. {
  3.     user u;
  4.     return u;              
  5. }
  6.  
Here, the function fail() makes use of the fact that the default constructor is called when an object of a class is initialized normally(without parameters).So basically, this function initializes an object u with username like "\0\0\0"(see the constructor of the user function) and returns this.Hence any object, which is returned from the function with username like "\0\0\0" is taken as failure.This proves the significance of using "return fail()" statement frequently.Also, there is no way of typing 4 null characters on the key board.Hence,this is the only way how this fail() value can be returned.Hence, no clashes can take place.I haven't directly returned the user() constructor directly b'coz it affects the program's understandability.

ok.Maybe the working of the fail() function would be a little confusing.But my point here is that the function fail () is not a constructor of some other class, nor does it return an object of some other class.Hence, there is no chance this can give corrupted values.

This program does not have a copy constructor defined in it. Instead, uses the copy constructor provided by the compiler, again b'coz of those 2 reasons, which I had already mentioned above(the reasons for not defining the operator '=').

Password as you would have recognized above, is a member of the class user.

The function user::change_password() doesn't use the this object.

Hopefully I have clarified all your doubts.
Dec 31 '15 #5
weaknessforcats
9,208 Expert Mod 8TB
I am trying to get a test program working but I find that inside user::change_password there is a login() but the function that was posted as user::login(short int pur) won't compile as a
login(). One has arguments and the other doesn't. Are there two login one of which is not a member function?
Dec 31 '15 #6
yeah.One is a non member function and the other the member function. Both functions have 1 parameter with default argument.The non member function just declares an object of user datatype, to invoke the member function.Here is the non member function, just in case u want-
Expand|Select|Wrap|Line Numbers
  1. inline user login(int pur=0)
  2. {
  3.     user u;
  4.     u=u.login(pur);
  5.     return u;
  6. }
  7.  
Dec 31 '15 #7
and the second statement in the change_password() function was
Expand|Select|Wrap|Line Numbers
  1. u=login(1
not
Expand|Select|Wrap|Line Numbers
  1. u=login()
.

I'd changed the statement for debugging purposes and had left it like that itself.Anyways, both show the same error though
Dec 31 '15 #8
weaknessforcats
9,208 Expert Mod 8TB
I am able to run your code without a crash using this main():

Expand|Select|Wrap|Line Numbers
  1. int main()
  2. {
  3.     user u;
  4.     user x("HELLO", "WORLD");
  5.  
  6.     u = x;
  7.  
  8.     u = fail();
  9.  
  10.     u = login(1);
  11. }
The only changes I made were:

1) a phony user.dat file
2) commented out //int pos = search(u, n, i); in user::change_password and set pos =0 instead. I didn't have the search function.

That said, there may be a problem in the search. That's the sort of thing where you can get a general protection fault.

My test main runs to completion with or without the debugger.

You might post the search code so I can add it to my test program.
Jan 1 '16 #9
Here is the code
Expand|Select|Wrap|Line Numbers
  1. int search(user a[],char b[],short int ub,int pur=0)
  2. {
  3.     for(int i=0;i<=ub;i++)
  4.     {
  5.         if(compare(a[i],b)==0)
  6.         {
  7.             if(pur!=0)
  8.             {
  9.                 a[i].display();
  10.                 getch();
  11.             }
  12.             return i;
  13.         }
  14.     }
  15.     if(pur!=0)
  16.         cout<<"User not found\n";
  17.     return -1;
  18. }
  19.  
Also note that in the main function,I didn't pass any parameters to login() function(The default val ie. 0 was hence the val of pur).I passed 1 as a parameter only in change_password() function.
Jan 1 '16 #10
OK, apart from this, as you mentioned the data file "users.dat" is the only requisite which is probably missing in the information which I have provided.Coincidentally, the error is shown after an fstream object f is declared (the fstream object is declared before the array of object u and the compiler stops just before declaration of this array of objects that is @ the statement fstream f("users.dat,ios::in|ios::out|ios::binary)).

Hence I'll provide you with my code of creating phony users.dat file-

Expand|Select|Wrap|Line Numbers
  1. #include<fstream.h>
  2. #include<conio.h>
  3. #include<stdio.h>
  4. #include<string.h>
  5. class user
  6. {
  7.     public:
  8.     char name[30],pass[30];
  9.     unsigned int pts,n_pts;
  10.     short int dif,a_dif,prev_mis,no_wins,cons_mis,cons_switch,tot_wins,loss;
  11.     float wrong;
  12.     user(char n[]="\0\0",char p[]="\0\0")
  13.     {
  14.         strcpy(name,n);
  15.         strcpy(pass,p);
  16.         pts=n_pts=dif=a_dif=prev_mis=no_wins=cons_mis=cons_switch=cons_switch=tot_wins=loss=wrong=0;
  17.     }
  18. };
  19. user fail()
  20. {
  21.     user a;
  22.     return a;
  23. }
  24. int compare(user a,user b)
  25. {
  26.     int ret=strcmpi(a.name,b.name);
  27.     return ret;
  28. }
  29. void main()
  30. {
  31.     cout<<"Are you sure you want to add sample users?\nOther contents may get destroyed\n(yes/no)\n";
  32.     char ch[10];
  33.     gets(ch);
  34.     if(strcmpi(ch,"yes")==0)
  35.     {
  36.         user u[6];
  37.         fstream f("users.dat",ios::out|ios::binary),f2("ldr brd.dat",ios::out|ios::binary);
  38.         strcpy(u[0].name,"admin");
  39.         strcpy(u[0].pass,"admin");
  40.         f.write((char*)&u[0],sizeof(user));
  41.         for(int i=1;i<5;i++)
  42.         {
  43.             char ch[15]="Sample ",no[2];
  44.             no[0]=i+48;
  45.             no[1]='\0';
  46.             strcat(ch,no);
  47.             strcpy(u[i].name,ch);
  48.             strcpy(u[i].pass,ch);
  49.             u[i].pts=(i-1)*100;
  50.             f.write((char*)&u[i],sizeof(user));
  51.         }
  52.         while(i>0)
  53.         {
  54.             if(compare(fail(),u[i])!=0)
  55.             {
  56.                 f2.write((char*)&u[i],sizeof(user));
  57.             }
  58.          i--;
  59.         }
  60.         cout<<"Successfully added\n";
  61.         f.close();
  62.         f2.close();
  63.     }
  64. }
  65.  
Hopefully, this helps you debug the error.
Jan 1 '16 #11
donbock
2,426 Expert 2GB
I'm more C than C++, so these comments may not be correct or pertinent...
  1. Lines 7-8 of user::login. What if users.dat contains more than 10 entries? Don't see anything in this loop to protect you from running past the end of u.
  2. Lines 8 and 13 of user::login; line 3 of search. Shouldn't line 3 of search be i<ub rather than i<=ub?
Jan 2 '16 #12
Thx donbock.But it actually doesn't help.
Jan 3 '16 #13
weaknessforcats
9,208 Expert Mod 8TB
I notice you are using gets() and not fgets(). gets() only works with stdin and copies to a buffer until it reaches a newline. It leaves the newline in stdin for the next operation to trip over and does not let you specify a buffer size leading to overruns followed by general protection faults
gets() has been removed from C++ in 2011 and is effectively removed from C.

You might consider using fgets().

In any case add some error checking code to test the return from gets() to see if any error occurred.
Jan 4 '16 #14

Sign in to post your reply or Sign up for a free account.

Similar topics

10
by: Sylvain Thenault | last post by:
Hi there ! Can someone explain me the following behaviour ? >>> l = >>> 0 in (l is False) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: iterable argument...
1
by: Jim Dawson | last post by:
I was writing a subroutine to extract fields from lines of text when I ran into an issue. I have reproduced this error on Perl 5.8 on AIX, 5.8 on Linux and 5.6 on Windows. ############### CUT...
4
by: gautam | last post by:
can anyone pls tell me y is the memory allocation not alligned to 4 Bytes. Note : compiled with gcc in linux 9 void function(int a,int b,int c) { char buffer1; Bytes allocated(as shown by gdb)...
1
by: Strange Cat | last post by:
Hi everyone! I have a weird problem with FormsAuthentication. I have an app that works just fine with FormsAuthentication. The user requests the homepage, he is redirected to login page,...
0
by: Alejandro Penate-Diaz | last post by:
I have two pages, each with one datagrid called "DataGrid1". Each DataGrid have a pushbutton implementing DeleteCommand, wich I am uing for a very different purpose tah actualy delete anything....
7
by: Vmrincon | last post by:
Hi everybody! I am trying to program a function in javascript and a funny behaviour occurs. If I execute this code: aux=parseInt(year-birthyear); return (aux)
0
by: probir.chatterjee | last post by:
Hi, Has anyone encountered similar problem before. I have an webpage in a webapplication that usesDataSet .WriteXml method to write a Log file. The page is meant to export out files in excel and...
5
by: Lars Hillebrand | last post by:
Hello, i discovered a weird behaviour if i use templates together with virtual inheritance and method over. I managed to reproduce my problem with a small example: // *********** <code...
0
by: RossGK | last post by:
I've been using pydev for a short while successfully, and Django with postgresql as well. psycopg2 is part of that behind the scenes I would imagine, to make django work. Now I'm trying to use...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.