0

When I call the test() function, it prompts me to enter the bet for the first player in my struct array. It accepts my entry. On the second round in my for loop, when asking for the bet for the second person in my struct array, an exception is thrown after a value is entered:

  Exception thrown at 0x00577F81 (ucrtbased.dll) in lottery.exe: 
  0xC0000005: Access violation writing location 0x7B7CC9FC.

  If there is a handler for this exception, the program may be safely continued. 

Here is my code:

void initNames(struct player *p, int size) {
  int i;
  for (i = 0; i < size; i++) {
      printf("Enter player %d's name...\n", (i + 1));
      scanf("%s", p[i].name);
  }
  return;
}

void initScore(struct player *p, int size) {
   int i;
   for (i = 0; i < size; i++) {
      p[i].wins = 0;
      p[i].losses = 0;
      p[i].funds = 100.00;
   }
   return;
}

void test(struct player *p, int size) {
  int i;
  for (i = 0; i < size; i++) {
    printf("%s, you have $%.2lf. Place your bet!\n", p[i].name, p[i].funds);
    scanf("%lf", p[i].bet);
  }
}

void main() {

  int size;
  struct player *playerPtr;

  printf("How many players?");
  scanf("%d", &size);
  playerPtr = malloc(sizeof(struct player)*size);

  initScore(&playerPtr, size);

  initNames(&playerPtr, size);

  test(&playerPtr, size);

  free(playerPtr);
}

Thanks for any help or explanations!

10
  • 3
    initScore(&playerPtr, size); --> initScore(playerPtr, size); and similarly for initNames and test Commented May 15, 2018 at 4:22
  • 1
    p[i].bet is the correct syntax. Since p is struct player *, p[i] is struct player and you can use .bet with it. Commented May 15, 2018 at 4:33
  • 1
    Write it up @AjayBrahmakshatriya - you identified the primary problem. Since the address of playerPtr is not changing in your functions -- there is no need to pass its address to the functions. Simply pass the pointer. The function will use a copy of the pointer, but the copy will point to (hold) the same address as the original -- thus any modifications within the functions will be reflected back in the caller (main() here) Commented May 15, 2018 at 4:39
  • 1
    Now if playerPtr was not allocated in main(), and you wished to pass the pointer to a function for allocation, then you would need to pass &playerPtr as player ** so you could assign the return from malloc to that very same pointer, e.g. *playerPtr = malloc (...) so that the allocation would be visible back in main(). In that case, if you just pass a pointer, you assign the address returned by malloc to a copy of the original and the lifetime of the copy only extends to that of the function -- leading to a memory leak and no allocated pointer in main(). Commented May 15, 2018 at 4:44
  • 1
    If you have removed the & then there should be no problem with the values assigned to the array in your functions (which by simple luck of your choice of format specifiers -- ignores leading whitespace more by happy accident than design, but on a matching failure an infinite loop will result) The only lingering issue is your use of p[i].bet instead of &p[i].bet when placing your bet. Always, always check the return of scanf, you must handle 3 cases every time: (1) EOF; (2) a matching or input failure; and lastly (3) successful conversions. Commented May 15, 2018 at 4:51

1 Answer 1

3

There is a discrepancy between how you have declared the function initNames and how you are calling it in main.

It is declared as -

void initNames(struct player *p, int size);

Which means it expects a pointer to struct player as the first argument and an int as the second.

In main you are calling it as -

struct player *playerPtr;
initNames(&playerPtr, size);

Now the type of playerPtr is struct player* and thus the type of &playerPtr will be struct player**. Thus there is a type mismatch for the arguments. Your compiler should have warned you about this. Always compile with -Wall to see all the warnings and -Werror to treat warnings as errors.

Coming to the fix -

You are not going to modify playerPtr inside any of the functions. So you need not pass struct player**. So change the call to function as -

initNames(playerPtr, size);

Nothing needs to be changed inside the function because the prototype for the function hasn't been changed.

The exact same issues are with the functions initScore and test too. You can fix them in a similar way by changing the first argument to their call.

Now after fixing this too, the program won't be correct. Look at the line -

scanf("%lf", p[i].bet);

I am assuming bet is declared with type double. You are now passing the double to scanf where a double* is expected. You need to pass the address of bet. So change the line to -

scanf("%lf", &p[i].bet);

I have fixed all the errors and the working version is at Ideone.

I have assumed a definition for struct player.

To be more sure about the values being read you should always check the return value of scanf as -

int ret = scanf("%lf", p[i].bet);

if(ret == 0) {
    // Print appropriate error message that the value entered in not a double and ask the user to retry
} else if (ret == EOF) {
    // The input stream has been closed by the user without providing appropriate input, print appropriate error message and abort. 
}
// If execution reaches this point, p[i].bet is safe to use.
Sign up to request clarification or add additional context in comments.

4 Comments

This makes a lot of sense to me. The problem I am now running into is an exception being thrown after inputting the first players bet. It throws the same exception that was happening to begin with. I am not sure why it is doing this since data is safely being written in the initScores() function.
See my last comment.
I fixed this by using &p[i].bet instead of p[i].bet in my scanf statement
@JohnBillingham I have added the fix to my answer. I see you have already fixed it though.

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.