C语言 排序结构字段时出现内存访问错误

wtzytmuj  于 2023-01-12  发布在  其他
关注(0)|答案(1)|浏览(116)

我在对一个结构字段排序时遇到一些问题,并且找不到为什么会发生这种情况的答案......当我运行程序时,错误消息显示“内存访问错误(德语:Speicherzugriffsfehler(Speicherabzug geschrieben))。只有当我尝试在bubblesort中执行以下行之一时,错误才会出现:

x= *mannschaften[i];
*mannschaften[i]=*mannschaften[i+1];
*mannschaften[i+1]=x;
vertauscht=1;

我有一种感觉,我可能必须在某个时候使用malloc()或calloc()来保存内存,但是我还不知道如何使用它...
谢谢你的帮助!最好的问候kazimir
你可以看到下面的整个代码:

#include <stdio.h>
#include <string.h>

typedef struct
{
    char* nation;
    int goals_scored;
    int goals_conceded;
} Team;

typedef struct
{
    Team* t1;
    Team* t2;
    int goals_t1;
    int goals_t2;
}Spiel;

void ergebnis_eintragen(Spiel s)
{
s.t1->goals_scored = s.goals_t1;
s.t2->goals_scored = s.goals_t2;
s.t1->goals_conceded = s.goals_t2;
s.t2->goals_conceded = s.goals_t1;
}

void ausgabe (Team* mannschaften[8])
{
    Team x;
    int m=8;
    int vertauscht;

    do
    {
        vertauscht=0;
        for (int i=0;i<8;i++)
        {
            if (mannschaften[i]->goals_scored<mannschaften[i+1]->goals_scored)
            {
                    x= *mannschaften[i];
                    *mannschaften[i]=*mannschaften[i+1];
                    *mannschaften[i+1]=x;
                    vertauscht=1;
            }

            else if (mannschaften[i]->goals_scored==mannschaften[i+1]->goals_scored||mannschaften[i]->goals_conceded>mannschaften[i+1]->goals_conceded)
            {
                    x = *mannschaften[i];
                    *mannschaften[i]=*mannschaften[i+1];
                    *mannschaften[i+1]=x;
                    vertauscht=1;
            }
        }
        m-=1;
    }
    while (m>1 && vertauscht);

    for (int i=0;i<8;i++)
        printf("\nNation: %s\nTore: %d\nGegentore: %d\n",mannschaften[i]->nation,mannschaften[i]->goals_scored,mannschaften[i]->goals_conceded);
}

int main (void)
{
    Team t1={"Kroatien",0,0};
    Team t2={"Brasilien",0,0};
    Team t3={"Niederlande",0,0};
    Team t4={"Argentinien",0,0};
    Team t5={"Marokko",0,0};
    Team t6={"Portugal",0,0};
    Team t7={"England",0,0};
    Team t8={"Frankreich",0,0};

    Spiel s1={&t1,&t2,5,3};
    Spiel s2={&t3,&t4,5,6};
    Spiel s3={&t5,&t6,1,0};
    Spiel s4={&t7,&t8,1,2};
    Spiel s5={&t4,&t1,3,0};
    Spiel s6={&t8,&t5,2,0};
    Spiel s7={&t1,&t5,2,1};
    Spiel s8={&t4,&t8,7,5};

    Team* ptr_team[8];
    ptr_team[0] = &t1;
    ptr_team[1] = &t2;
    ptr_team[2] = &t3;
    ptr_team[3] = &t4;
    ptr_team[4] = &t5;
    ptr_team[5] = &t6;
    ptr_team[6] = &t7;
    ptr_team[7] = &t8;
    
    ergebnis_eintragen(s1);
    ergebnis_eintragen(s2);
    ergebnis_eintragen(s3);
    ergebnis_eintragen(s4);
    ergebnis_eintragen(s5);
    ergebnis_eintragen(s6);
    ergebnis_eintragen(s7);
    ergebnis_eintragen(s8);
    
    ausgabe(&ptr_team[0]);
}

我已经尝试寻找一个模拟问题,但找不到任何东西...

t40tm48m

t40tm48m1#

在for循环中

for (int i=0;i<8;i++)
    {
        if (mannschaften[i]->goals_scored<mannschaften[i+1]->goals_scored)

i等于7时,表达式如下

mannschaften[i+1]->goals_scored)

访问main中定义的数组ptr_team之外的内存。
你可以这样写循环

for (int i=1;i<8;i++)
    {
        if (mannschaften[i-1]->goals_scored<mannschaften[i]->goals_scored)
        //...

而且在if语句中

else if (mannschaften[i]->goals_scored==mannschaften[i+1]->goals_scored||mannschaften[i]->goals_conceded>mannschaften[i+1]->goals_conceded)

您指的是逻辑运算符&&而不是逻辑运算符||

else if (mannschaften[i]->goals_scored==mannschaften[i+1]->goals_scored && mannschaften[i]->goals_conceded>mannschaften[i+1]->goals_conceded)

在do-while循环中使用变量m没有多大意义,使用变量vertauscht就足够了

do
{
    //...
} while ( vertauscht);

而且使用像8这样的幻数是个坏主意。
可以像这样声明函数

void ausgabe (Team* mannschaften[], size_t n );

至少可以称之为

ausgabe( ptr_team, 8 );

然后在函数中,您应该使用变量n而不是幻数8,例如

for ( size_t i = 1;i < n;i++ )

否则,每当传递的数组的大小发生变化时,您都需要更改函数。
你应该写一个更通用的函数。
请注意,如果您使用英语单词作为标识符,您的程序看起来会更好,可读性也会更强。

相关问题