1

Whenever I run this struct, I can get down to the line where you would input the constitution modifier and the program crashes with a popup window which reads "The instruction at 0x00000000775AFDE9 referenced memory at 0x000000007758D250. The memory could not be written. Press OK to terminate." Here's the struct in question:

struct player_info create_player(void);
struct player_info{
    char name[30];
    int Level, Str, Dex, Con, Int, Wis, Cha;
};

struct player_info create_player(void){
    struct player_info aPlayer;
    {
        char c;
        int i;
        printf("Enter Player Name: ");
        scanf("%s",aPlayer.name);
        i = strlen(aPlayer.name);
        do{
            scanf("%c", &c);
            aPlayer.name[i++] = c;
        }
        while (c != '\n');
        aPlayer.name[i - 1] = 0;
    }

    printf("Level: ");
    scanf("%d",aPlayer.Level);

    printf("Strength Modifier: ");
    scanf("%d",aPlayer.Str);

    printf("Dexterity Modifier: ");
    scanf("%d", aPlayer.Dex);

    printf("Constitution Modifier: ");
    scanf("%d", aPlayer.Con);

    printf("Intelligence Modifier: ");
    scanf("%d", aPlayer.Int);

    printf("Wisdom Modifier: ");
    scanf("%d", aPlayer.Wis);

    printf("Charisma Modifier: ");
    scanf("%d", aPlayer.Cha);
    return aPlayer;
};

And the write bit:

int save_data(){
             FILE* PlayerFile = fopen("players.txt","w");
             int i = 0;

             for (i = 0; i < 1; i++){
             struct player_info aPlayer = create_player();
             fprintf(PlayerFile, "%s %d %d %d %d %d %d %d\n", aPlayer.name, aPlayer.Level, aPlayer.Str, aPlayer.Dex, aPlayer.Con, aPlayer.Int, aPlayer.Wis, aPlayer.Cha);
             }
             fclose(PlayerFile);
             return 0;
             }

Now, to be clear, I can input up to the dexterity modifier. The next line that should ask for the constitution doesn't print, and that's when I get the popup error.

I have tried commenting out everything from the constitution mod down to the charisma just to see, and I get the same problem. Removing just the constitution part doesn't work either. I'm not really sure what's going on here; I've seen other posts saying something about a pointer being wrong, but I don't see anything like that, unless it's just one of those things that you just miss and need someone else to point it out. Anyway, any help is appreciated.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
hego64
  • 345
  • 1
  • 5
  • 17
  • 2
    [Turn up your warnings to pedantic levels](http://pastebin.com/zUvX0UQi). – WhozCraig Feb 19 '17 at 07:52
  • when calling any of the `scanf()` family of functions, always check the returned value (not the parameter value) to assure the operation was successful. – user3629249 Feb 19 '17 at 17:19
  • the function: `strlen()` returns a `size_t` not a `int` – user3629249 Feb 19 '17 at 17:21
  • when calling any of the `scanf()` family of functions: 1) always check the returned value (not the parameter values) to assure the operation was successful. 2) when using the `%s` format specifier, always include a MAX CHARACTERS modifier that is one less than the length of the input buffer so a buffer overflow cannot occur. – user3629249 Feb 19 '17 at 17:23
  • a lot of code can be eliminated by replacing: `scanf("%s",aPlayer.name);` and the following lines with: `scanf("%[^\n]",aPlayer.name);` – user3629249 Feb 19 '17 at 17:26
  • the posted code is returning a local variable (on the stack) When the function exits, that variable goes out of scope, so will be corrupted. Suggest using `calloc()` or `malloc()` to allocate memory for the struct then return the pointer to that memory. – user3629249 Feb 19 '17 at 17:29
  • when compiling, always enable all the warnings, then fix those warnings. (for `gcc`, at a minimum use: `-Wall -Wextra -pedantic` I also use: `-Wconversion -std=gnu99` ) – user3629249 Feb 19 '17 at 17:35
  • Thanks for all the info. By the way, I had tried using `scanf("%[^\n]",aPlayer.name);` several times before, and it never worked for me. Anyway, thanks for the rest of the info. – hego64 Feb 20 '17 at 00:58

1 Answers1

4

scanf expects the address of the variable you intend to write to. So this

scanf("%d",aPlayer.Level);

Should be this

scanf("%d", &aPlayer.Level);

For all of your stats. The way you have it setup now involves passing an unspecified integral value to scanf (the variable aPlayer.Level and company are uninitialized), which is then reinterpreted as an address that the function attempts to write into. The behavior of of such code is undefined.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • I'd completely forgotten about that, thank you. I've changed them all, but unless I've missed something, I'm still getting the same error. – hego64 Feb 19 '17 at 07:56
  • @hego64 - Start with follow the advice by WhozCraig. And post another question if it doesn't help. The only other suspicious looking thing in your code is the whole do..while loop with `aPlayer.name`. But you claim it works, so I'll leave it at that. – StoryTeller - Unslander Monica Feb 19 '17 at 07:58
  • I actually got that from another question I'd asked here. That code there is the one I based this off. http://stackoverflow.com/a/41896154/7471023 And how exactly can I turn up the warnings like he suggested? – hego64 Feb 19 '17 at 08:01
  • @hego64 - The person who answered that went out of his way so you could get user input with spaces in between. They should have just offered something other than `scanf`, such as `fgets(buff, buff_len, stdin);` – StoryTeller - Unslander Monica Feb 19 '17 at 08:05
  • @hego64 - as for the warnings, consult your compiler documentation. [This is the relevant info for GCC](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html), for example. So it would be something like `-Wall -Wextra -pedantic -Werror -pedantic-errors` – StoryTeller - Unslander Monica Feb 19 '17 at 08:06
  • I guess it may be a bit more complicated than it needs to be, but that doesn't seem to be the problem. It works fine in that other struct, and I don't have any problems with this one until after that has been passed. – hego64 Feb 19 '17 at 08:09
  • @hego64 - (shrug) Then take a good hard look at your code. I did at what you posted and that's what is wrong with it. – StoryTeller - Unslander Monica Feb 19 '17 at 08:11
  • Okay, I'm an idiot. Yes, you were absolutely right that that was the problem, and as I said I had forgotten about needing to add that. The reason it wasn't working was because I had 2 files open, one with just the struct, and the other with the full program including the struct. I had been editing the wrong one and compiling the other. So yeah. Corrected, and it functions properly. Thank you. I'm really starting to see the value in "rubber duck debugging", which is basically what this is, except you actually get feedback. Anyway, I feel dumb for doing that now. Thanks again man. – hego64 Feb 19 '17 at 08:16