内存访问错误在排序结构字段时发生。

huangapple go评论71阅读模式
英文:

memory access error when sorting struct field

问题

我有一些问题需要对结构字段进行排序,但找不到为什么会发生这种情况的答案...
当我运行程序时出现错误消息,说"内存访问错误(德语:Speicherzugriffsfehler (Speicherabzug geschrieben))。只有当我尝试执行以下冒泡排序中的一行时,错误才会出现:

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

我有一种感觉,我可能需要在某个时候使用malloc()或calloc()来保存内存,但我不知道如何使用它,但现在...

感谢您的帮助!
最好的问候
卡兹米尔

您可以在下面看到完整的代码:

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

我已经尝试寻找类似的问题,但找不到任何信息...

英文:

i have some problems sorting a struct field and cannot find the answer why this is happening...
The Error message when i run the program says "Memory access error (German: Speicherzugriffsfehler (Speicherabzug geschrieben)). The error only comes whenever i try the proceed one of the following lines in the bubblesort:

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

I have the feeling that i might have to save memory with malloc() or calloc() at some point, but i don't know how to use this,yet...

Thank you for your help!
Best regards
kazimir

You can see the the entire code below:

#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
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-&gt;goals_scored = s.goals_t1;
s.t2-&gt;goals_scored = s.goals_t2;
s.t1-&gt;goals_conceded = s.goals_t2;
s.t2-&gt;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&lt;8;i++)
{
if (mannschaften[i]-&gt;goals_scored&lt;mannschaften[i+1]-&gt;goals_scored)
{
x= *mannschaften[i];
*mannschaften[i]=*mannschaften[i+1];
*mannschaften[i+1]=x;
vertauscht=1;
}
else if (mannschaften[i]-&gt;goals_scored==mannschaften[i+1]-&gt;goals_scored||mannschaften[i]-&gt;goals_conceded&gt;mannschaften[i+1]-&gt;goals_conceded)
{
x = *mannschaften[i];
*mannschaften[i]=*mannschaften[i+1];
*mannschaften[i+1]=x;
vertauscht=1;
}
}
m-=1;
}
while (m&gt;1 &amp;&amp; vertauscht);
for (int i=0;i&lt;8;i++)
printf(&quot;\nNation: %s\nTore: %d\nGegentore: %d\n&quot;,mannschaften[i]-&gt;nation,mannschaften[i]-&gt;goals_scored,mannschaften[i]-&gt;goals_conceded);
}
int main (void)
{
Team t1={&quot;Kroatien&quot;,0,0};
Team t2={&quot;Brasilien&quot;,0,0};
Team t3={&quot;Niederlande&quot;,0,0};
Team t4={&quot;Argentinien&quot;,0,0};
Team t5={&quot;Marokko&quot;,0,0};
Team t6={&quot;Portugal&quot;,0,0};
Team t7={&quot;England&quot;,0,0};
Team t8={&quot;Frankreich&quot;,0,0};
Spiel s1={&amp;t1,&amp;t2,5,3};
Spiel s2={&amp;t3,&amp;t4,5,6};
Spiel s3={&amp;t5,&amp;t6,1,0};
Spiel s4={&amp;t7,&amp;t8,1,2};
Spiel s5={&amp;t4,&amp;t1,3,0};
Spiel s6={&amp;t8,&amp;t5,2,0};
Spiel s7={&amp;t1,&amp;t5,2,1};
Spiel s8={&amp;t4,&amp;t8,7,5};
Team* ptr_team[8];
ptr_team[0] = &amp;t1;
ptr_team[1] = &amp;t2;
ptr_team[2] = &amp;t3;
ptr_team[3] = &amp;t4;
ptr_team[4] = &amp;t5;
ptr_team[5] = &amp;t6;
ptr_team[6] = &amp;t7;
ptr_team[7] = &amp;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(&amp;ptr_team[0]);
}

I already tried looking for a simular question, but couldn't find anything...

答案1

得分: 1

In the for loop:

在这个for循环中:

for (int i=0;i&lt;8;i++)
{
    if (mannschaften[i]-&gt;goals_scored&lt;mannschaften[i+1]-&gt;goals_scored)

when i is equal to 7 then expressions like this:

i等于7时,像这样的表达式:

mannschaften[i+1]-&gt;goals_scored)

access memory outside the array ptr_team defined in main.

访问了在主函数中定义的ptr_team数组之外的内存。

You could write your loop like for example:

你可以像这样重写你的循环,例如:

for (int i=1;i&lt;8;i++)
{
    if (mannschaften[i-1]-&gt;goals_scored&lt;mannschaften[i]-&gt;goals_scored)
    //...

Also it seems in this if statement:

此外,似乎在这个if语句中:

else if (mannschaften[i]-&gt;goals_scored==mannschaften[i+1]-&gt;goals_scored||mannschaften[i]-&gt;goals_conceded&gt;mannschaften[i+1]-&gt;goals_conceded)

you mean the logical operator && instead of the logical operator ||.

你的意思是逻辑运算符&&而不是逻辑运算符||

else if (mannschaften[i]-&gt;goals_scored==mannschaften[i+1]-&gt;goals_scored &amp;&amp; mannschaften[i]-&gt;goals_conceded&gt;mannschaften[i+1]-&gt;goals_conceded)

Using the variable m as is in the do-while loop does not make great sense. It is enough to use the variable vertauscht.

在do-while循环中使用变量m似乎没有太大意义。只使用变量vertauscht就足够了。

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

And it is a bad idea to use magic numbers like 8.

而且使用像8这样的魔法数字是一个不好的主意。

You could declare your function like:

你可以像这样声明你的函数:

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

and call it like:

并且像这样调用它:

ausgabe( ptr_team, 8 );

Then within the function, you should use the variable n instead of the magic number 8, for example:

然后在函数内部,你应该使用变量n而不是魔法数字8,例如:

for ( size_t i = 1;i &lt; n;i++ )

Otherwise, you will need to change your function each time when the size of the passed array will be changed.

否则,每当传递的数组大小发生变化时,你都需要更改你的函数。

You should always write a more general function.

你应该总是编写更通用的函数。

Pay attention to the fact that your program will look much better and will be more readable if you use English words for identifiers.

注意,如果你在标识符中使用英文单词,你的程序看起来会更好,更易读。

英文:

In the for loop

    for (int i=0;i&lt;8;i++)
{
if (mannschaften[i]-&gt;goals_scored&lt;mannschaften[i+1]-&gt;goals_scored)

when i is equal to 7 then expressions like this

mannschaften[i+1]-&gt;goals_scored)

access memory outside the array ptr_team defined in main.

You could write your loop like for example

    for (int i=1;i&lt;8;i++)
{
if (mannschaften[i-1]-&gt;goals_scored&lt;mannschaften[i]-&gt;goals_scored)
//...

Also it seems in this if statement

else if (mannschaften[i]-&gt;goals_scored==mannschaften[i+1]-&gt;goals_scored||mannschaften[i]-&gt;goals_conceded&gt;mannschaften[i+1]-&gt;goals_conceded)

you mean the logical operator &amp;&amp; instead of the logical operator ||

else if (mannschaften[i]-&gt;goals_scored==mannschaften[i+1]-&gt;goals_scored &amp;&amp; mannschaften[i]-&gt;goals_conceded&gt;mannschaften[i+1]-&gt;goals_conceded)

Using the variable m as is in the do-while loop does not make a great sense. It is enough to use the variable vertauscht

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

And it is a bad idea to use magic numbers like 8.

You could declare your function like

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

and call it at least like

ausgabe( ptr_team, 8 );

Then within the function you should use the variable n instead of the magic number 8 as for example

for ( size_t i = 1;i &lt; n;i++ )

Otherwise you will need to change your function each time when the size of the passed array will be changed.

You should always write a more general function.

Pay attention to that your program will look much better and will be more readable if you will use English words for identifiers.

huangapple
  • 本文由 发表于 2023年1月9日 19:25:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/75056589.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定