You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

访问结构体数组时抛出异常的问题排查求助

问题分析与修复:访问违例异常解决

首先看你遇到的异常:

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.

这通常是非法内存访问导致的,咱们来拆解你代码里的问题:

你的原始代码

#include <stdio.h>
#include <stdlib.h>

// 补充你未粘贴的player结构体定义(推测合理结构)
struct player {
    char name[50];
    int wins;
    int losses;
    double funds;
    double bet;
};

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); // 错误点1
    } 
} 

void main() { 
    int size; 
    struct player *playerPtr; 
    printf("How many players?"); 
    scanf("%d", &size); 
    playerPtr = malloc(sizeof(struct player)*size); 
    initScore(&playerPtr, size); // 错误点2
    initNames(&playerPtr, size); // 错误点2
    test(&playerPtr, size); // 错误点2
    free(playerPtr); 
} 

关键错误点及修复

  1. 指针传递类型不匹配
    在main里,playerPtr已经是struct player*类型(指向结构体数组的指针),但你调用三个初始化/测试函数时,传递的是&playerPtr——也就是struct player**(指针的指针),和函数要求的struct player*参数类型完全不匹配。这种错误会让函数内部错误解析内存地址,直接导致非法访问。

    修复:直接传递playerPtr即可,不需要取地址:

    initScore(playerPtr, size);
    initNames(playerPtr, size);
    test(playerPtr, size);
    
  2. scanf缺少取地址符
    test函数里的scanf("%lf", p[i].bet);是典型错误:scanf对于double这类基本类型,必须传入变量的地址,否则它会把输入的值写到p[i].bet当前值对应的内存位置——这个位置几乎肯定是不属于程序的非法内存,触发访问违例。

    修复:给p[i].bet加上取地址符&:

    scanf("%lf", &p[i].bet);
    
  3. main函数返回值不规范
    标准C中main的返回类型必须是int而非void,虽然这不是直接引发异常的原因,但不符合语言规范,建议修正:

    int main() {
        // ... 原有代码
        free(playerPtr);
        return 0; // 添加返回值
    }
    

修正后的完整代码

#include <stdio.h>
#include <stdlib.h>

struct player {
    char name[50];
    int wins;
    int losses;
    double funds;
    double bet;
};

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

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

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); // 修正:添加取地址符
    } 
} 

int 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); 
    return 0; // 修正:添加返回值
} 

修复逻辑说明

  • 指针传递修正后,函数能正确访问playerPtr指向的结构体数组内存,避免地址解析错误;
  • scanf添加取地址符后,输入值会被正确写入到p[i].bet的内存位置,不会触发非法访问;
  • 修正main返回值是遵循C标准的健壮性做法。

内容的提问来源于stack exchange,提问作者hax

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:54:53