0

In my code I have an Array of class User as a private variable in class UserManager. When UserManager::Shutdown() is called it save the Array of Users to a file. Yet I get an access violation error. The Access violation error occurs in fwrite.c

I am compiling on Visual Studio 2010 running Windows 7.

User Class

class User {
public:
User() {
    memset(username, 0, 255);
    memset(password, 0, 255);
}

int userId;
char username[255];
char password[255];
};

MAX_USERS Definition

#define MAX_USERS 2048

User Manager Constructor

UserManager::UserManager() {
memset( users, 0, MAX_USERS);
}

Shutdown Function

void UserManager::Shutdown( void) {
FILE *userDB = fopen( "users.bin", "wb");
int k=1;
for(k=1;k<MAX_USERS-1;k++){
    if (users[k]!=NULL) {
        fwrite((const void*)&users[k]->userId, sizeof(int), 1, userDB);
        fwrite((const void*)users[k]->username, 255, 1, userDB);
        fwrite((const void*)users[k]->password, 255, 1, userDB);
    } else {
        fpos_t skip = 255 + 255 + sizeof(int);
        fsetpos( userDB, &skip);
    }
}

fclose( userDB);
}

The array 'users' is memset to zero at the constructor.

4
  • 1
    The else block where you skip and reset the file pointer position seems problematic (Try writing an 'empty' record instead of skipping). Did u run it thru the debugger to see where/when exactly is the access violation? Commented Apr 13, 2011 at 19:22
  • It would help if we knew how users is declared, and how it is initialized. My guess: it is an array of uninitialized pointers to User. Commented Apr 13, 2011 at 19:27
  • I had it writing a NULL user, but it still gave me an access violation. It was happening when writing the user id until I changed it. Commented Apr 13, 2011 at 19:28
  • users is memset to 0 in the constructor of UserManager Commented Apr 13, 2011 at 19:30

2 Answers 2

1

Theory 1

Your loop iteration starts at 1, but array indexing starts at 0. Without seeing the definition of MAX_USERS or the actual error my guess is your k value is overrunning your users array boundary.

Theory 2

You declared users as

User *users[MAX_USERS] = {};

Then you didn't new up each user when you created them. So, instead of

users[index] = new User();

you did

  User user1;
  users[index] = &user1;

The second version would probably go out of scope. Then the memory for user1 would be reallocated somewhere else and when you tried to access it via users[k]-> you get the access violation.

My version

Below is the code I used to try figure out the problem. It's quick and dirty with me filling in the gaps but it runs to completion. Hopefully it will help.

#define MAX_USERS 2048
class User { 
    public: User() {     
    memset(username, 0, 255);     
    memset(password, 0, 255); }  
    int userId; 
    char username[255]; 
    char password[255]; 
}; 

void writefile( User **users)
{
    FILE *userDB = fopen( "users.bin", "wb"); 
    int k=0; for(k=0;k<MAX_USERS-1;k++){     
        if (users[k]!=NULL) {         
            fwrite((const void*)&users[k]->userId, sizeof(int), 1, userDB);         
            fwrite((const void*)users[k]->username, 255, 1, userDB);         
            fwrite((const void*)users[k]->password, 255, 1, userDB);     
            fprintf(stdout, "UserID %d\n", users[k]->userId);
            fprintf(stdout, "%s\n", users[k]->username);
            fprintf(stdout, "%s\n", users[k]->password);
            fflush(stdout);
        } else {         
            fpos_t skip = 255 + 255 + sizeof(int);         
            fsetpos( userDB, &skip);     
        } 
    }  fclose( userDB); 
} 

int _tmain(int argc, _TCHAR* argv[])
{
    User *users[MAX_USERS] = {};
    memset(users, 0, MAX_USERS);
    users[0] = new User();
    users[0]->userId = 1;
    memcpy(users[0]->username,"BLah", strlen("BLah"));
    memcpy(users[0]->password,"something:", strlen("something:"));
    users[2] = new User();
    users[2]->userId = 1;
    memcpy(users[2]->username,"BLah2", strlen("BLah2"));
    memcpy(users[2]->password,"something:", strlen("something:"));
    writefile(users);

    return 0;
}
Sign up to request clarification or add additional context in comments.

5 Comments

That is a problem, but not causing the access violation error.
Like Rob said. I would really help if we could see the declaration of 'users', 'MAX_USERS' and how 'users' was initialized/populated.
added all of it to the OP. users are added with a RegisterUser() function, but that works fine.
Are you sure you changed int k=1; and the k=1 in the for loop? The code posted seemed to work when made sure that k was initialize to zero. Of course there were gaps I had to fill in, so it wasn't identical to your code.
then that is memset to zero so both theories are wrong. I have analyzed the array during run time, nothing is wrong with the for loop or the users. The problem is the Binary File IO. Writing the actual Data.
0

Are you initializing all variables ?
The suspicion is that the array is the cause.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.