【问题标题】:Referenced memory could not be written无法写入引用的内存
【发布时间】:2017-02-19 07:42:52
【问题描述】:

每当我运行这个结构时,我都可以进入输入宪法修饰符的行,程序崩溃并弹出一个窗口,上面写着“0x00000000775AFDE9 处的指令引用了 0x000000007758D250 处的内存。无法写入内存。按 OK 终止。”这是有问题的结构:

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;
};

还有写位:

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;
             }

现在,需要明确的是,我可以输入至多灵巧修饰符。应该要求宪法的下一行没有打印出来,那是我收到弹出错误的时候。

我尝试评论从宪法模式到魅力的所有内容,只是为了看看,我遇到了同样的问题。仅删除宪法部分也不起作用。我不太确定这里发生了什么。我看到其他帖子说指针错误,但我没有看到类似的东西,除非它只是你错过的那些事情之一并且需要其他人指出它。无论如何,感谢任何帮助。

【问题讨论】:

  • 在调用任何scanf() 系列函数时,始终检查返回值(而不是参数值)以确保操作成功。
  • 函数:strlen() 返回 size_t 而不是 int
  • 在调用任何scanf() 系列函数时: 1) 始终检查返回值(而不是参数值)以确保操作成功。 2) 使用%s 格式说明符时,始终包含比输入缓冲区长度小1 的MAX CHARACTERS 修饰符,因此不会发生缓冲区溢出。
  • 很多代码可以通过替换:scanf("%s",aPlayer.name); 和以下行替换为:scanf("%[^\n]",aPlayer.name);

标签: c memory struct runtime-error


【解决方案1】:

scanf 需要您打算写入的变量的地址。所以这个

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

应该是这个

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

您的所有统计数据。现在设置它的方式涉及将未指定的整数值传递给scanf(变量aPlayer.Level 和公司未初始化),然后将其重新解释为函数尝试写入的地址。此类代码的行为未定义。

【讨论】:

  • 我完全忘记了这一点,谢谢。我已经全部更改了,但除非我遗漏了什么,否则我仍然会遇到同样的错误。
  • @hego64 - 从 WhozCraig 的建议开始。如果没有帮助,请发布另一个问题。您的代码中唯一看起来可疑的东西是带有aPlayer.name 的整个do..while 循环。但是您声称它有效,所以我将保留它。
  • 我实际上是从我在这里问的另一个问题中得到的。该代码是我基于此的代码。 stackoverflow.com/a/41896154/7471023 我怎么能像他建议的那样打开警告?
  • @hego64 - 回答这个问题的人不顾一切,这样你就可以得到用户输入,中间有空格。他们应该只是提供了 scanf 以外的东西,例如 fgets(buff, buff_len, stdin);
  • @hego64 - 至于警告,请查阅您的编译器文档。 This is the relevant info for GCC,例如。所以它会像-Wall -Wextra -pedantic -Werror -pedantic-errors
猜你喜欢
  • 2013-11-28
  • 1970-01-01
  • 1970-01-01
  • 2021-05-13
  • 2018-05-15
  • 2021-10-14
  • 1970-01-01
  • 1970-01-01
  • 2011-12-05
相关资源
最近更新 更多