英文:
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 <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 already tried looking for a simular question, but couldn't find anything...
答案1
得分: 1
In the for loop:
在这个for循环中:
for (int i=0;i<8;i++)
{
if (mannschaften[i]->goals_scored<mannschaften[i+1]->goals_scored)
when i
is equal to 7
then expressions like this:
当i
等于7
时,像这样的表达式:
mannschaften[i+1]->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<8;i++)
{
if (mannschaften[i-1]->goals_scored<mannschaften[i]->goals_scored)
//...
Also it seems in this if statement:
此外,似乎在这个if语句中:
else if (mannschaften[i]->goals_scored==mannschaften[i+1]->goals_scored||mannschaften[i]->goals_conceded>mannschaften[i+1]->goals_conceded)
you mean the logical operator &&
instead of the logical operator ||
.
你的意思是逻辑运算符&&
而不是逻辑运算符||
。
else if (mannschaften[i]->goals_scored==mannschaften[i+1]->goals_scored && mannschaften[i]->goals_conceded>mannschaften[i+1]->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 < 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<8;i++)
{
if (mannschaften[i]->goals_scored<mannschaften[i+1]->goals_scored)
when i
is equal to 7
then expressions like this
mannschaften[i+1]->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<8;i++)
{
if (mannschaften[i-1]->goals_scored<mannschaften[i]->goals_scored)
//...
Also it seems in this if statement
else if (mannschaften[i]->goals_scored==mannschaften[i+1]->goals_scored||mannschaften[i]->goals_conceded>mannschaften[i+1]->goals_conceded)
you mean the logical operator &&
instead of the logical operator ||
else if (mannschaften[i]->goals_scored==mannschaften[i+1]->goals_scored && mannschaften[i]->goals_conceded>mannschaften[i+1]->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 < 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论