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

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

memory access error when sorting struct field

问题

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

  1. x = *mannschaften[i];
  2. *mannschaften[i] = *mannschaften[i + 1];
  3. *mannschaften[i + 1] = x;
  4. vertauscht = 1;

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

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

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

  1. #include <stdio.h>
  2. #include <string.h>
  3. typedef struct
  4. {
  5. char* nation;
  6. int goals_scored;
  7. int goals_conceded;
  8. } Team;
  9. typedef struct
  10. {
  11. Team* t1;
  12. Team* t2;
  13. int goals_t1;
  14. int goals_t2;
  15. } Spiel;
  16. void ergebnis_eintragen(Spiel s)
  17. {
  18. s.t1->goals_scored = s.goals_t1;
  19. s.t2->goals_scored = s.goals_t2;
  20. s.t1->goals_conceded = s.goals_t2;
  21. s.t2->goals_conceded = s.goals_t1;
  22. }
  23. void ausgabe(Team* mannschaften[8])
  24. {
  25. Team x;
  26. int m = 8;
  27. int vertauscht;
  28. do
  29. {
  30. vertauscht = 0;
  31. for (int i = 0; i < 8; i++)
  32. {
  33. if (mannschaften[i]->goals_scored < mannschaften[i + 1]->goals_scored)
  34. {
  35. x = *mannschaften[i];
  36. *mannschaften[i] = *mannschaften[i + 1];
  37. *mannschaften[i + 1] = x;
  38. vertauscht = 1;
  39. }
  40. else if (mannschaften[i]->goals_scored == mannschaften[i + 1]->goals_scored || mannschaften[i]->goals_conceded > mannschaften[i + 1]->goals_conceded)
  41. {
  42. x = *mannschaften[i];
  43. *mannschaften[i] = *mannschaften[i + 1];
  44. *mannschaften[i + 1] = x;
  45. vertauscht = 1;
  46. }
  47. }
  48. m -= 1;
  49. } while (m > 1 && vertauscht);
  50. for (int i = 0; i < 8; i++)
  51. printf("\nNation: %s\nTore: %d\nGegentore: %d\n", mannschaften[i]->nation, mannschaften[i]->goals_scored, mannschaften[i]->goals_conceded);
  52. }
  53. int main(void)
  54. {
  55. Team t1 = { "Kroatien", 0, 0 };
  56. Team t2 = { "Brasilien", 0, 0 };
  57. Team t3 = { "Niederlande", 0, 0 };
  58. Team t4 = { "Argentinien", 0, 0 };
  59. Team t5 = { "Marokko", 0, 0 };
  60. Team t6 = { "Portugal", 0, 0 };
  61. Team t7 = { "England", 0, 0 };
  62. Team t8 = { "Frankreich", 0, 0 };
  63. Spiel s1 = { &t1, &t2, 5, 3 };
  64. Spiel s2 = { &t3, &t4, 5, 6 };
  65. Spiel s3 = { &t5, &t6, 1, 0 };
  66. Spiel s4 = { &t7, &t8, 1, 2 };
  67. Spiel s5 = { &t4, &t1, 3, 0 };
  68. Spiel s6 = { &t8, &t5, 2, 0 };
  69. Spiel s7 = { &t1, &t5, 2, 1 };
  70. Spiel s8 = { &t4, &t8, 7, 5 };
  71. Team* ptr_team[8];
  72. ptr_team[0] = &t1;
  73. ptr_team[1] = &t2;
  74. ptr_team[2] = &t3;
  75. ptr_team[3] = &t4;
  76. ptr_team[4] = &t5;
  77. ptr_team[5] = &t6;
  78. ptr_team[6] = &t7;
  79. ptr_team[7] = &t8;
  80. ergebnis_eintragen(s1);
  81. ergebnis_eintragen(s2);
  82. ergebnis_eintragen(s3);
  83. ergebnis_eintragen(s4);
  84. ergebnis_eintragen(s5);
  85. ergebnis_eintragen(s6);
  86. ergebnis_eintragen(s7);
  87. ergebnis_eintragen(s8);
  88. ausgabe(&ptr_team[0]);
  89. }

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

英文:

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:

  1. x= *mannschaften[i];
  2. *mannschaften[i]=*mannschaften[i+1];
  3. *mannschaften[i+1]=x;
  4. 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:

  1. #include &lt;stdio.h&gt;
  2. #include &lt;string.h&gt;
  3. typedef struct
  4. {
  5. char* nation;
  6. int goals_scored;
  7. int goals_conceded;
  8. } Team;
  9. typedef struct
  10. {
  11. Team* t1;
  12. Team* t2;
  13. int goals_t1;
  14. int goals_t2;
  15. }Spiel;
  16. void ergebnis_eintragen(Spiel s)
  17. {
  18. s.t1-&gt;goals_scored = s.goals_t1;
  19. s.t2-&gt;goals_scored = s.goals_t2;
  20. s.t1-&gt;goals_conceded = s.goals_t2;
  21. s.t2-&gt;goals_conceded = s.goals_t1;
  22. }
  23. void ausgabe (Team* mannschaften[8])
  24. {
  25. Team x;
  26. int m=8;
  27. int vertauscht;
  28. do
  29. {
  30. vertauscht=0;
  31. for (int i=0;i&lt;8;i++)
  32. {
  33. if (mannschaften[i]-&gt;goals_scored&lt;mannschaften[i+1]-&gt;goals_scored)
  34. {
  35. x= *mannschaften[i];
  36. *mannschaften[i]=*mannschaften[i+1];
  37. *mannschaften[i+1]=x;
  38. vertauscht=1;
  39. }
  40. 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)
  41. {
  42. x = *mannschaften[i];
  43. *mannschaften[i]=*mannschaften[i+1];
  44. *mannschaften[i+1]=x;
  45. vertauscht=1;
  46. }
  47. }
  48. m-=1;
  49. }
  50. while (m&gt;1 &amp;&amp; vertauscht);
  51. for (int i=0;i&lt;8;i++)
  52. printf(&quot;\nNation: %s\nTore: %d\nGegentore: %d\n&quot;,mannschaften[i]-&gt;nation,mannschaften[i]-&gt;goals_scored,mannschaften[i]-&gt;goals_conceded);
  53. }
  54. int main (void)
  55. {
  56. Team t1={&quot;Kroatien&quot;,0,0};
  57. Team t2={&quot;Brasilien&quot;,0,0};
  58. Team t3={&quot;Niederlande&quot;,0,0};
  59. Team t4={&quot;Argentinien&quot;,0,0};
  60. Team t5={&quot;Marokko&quot;,0,0};
  61. Team t6={&quot;Portugal&quot;,0,0};
  62. Team t7={&quot;England&quot;,0,0};
  63. Team t8={&quot;Frankreich&quot;,0,0};
  64. Spiel s1={&amp;t1,&amp;t2,5,3};
  65. Spiel s2={&amp;t3,&amp;t4,5,6};
  66. Spiel s3={&amp;t5,&amp;t6,1,0};
  67. Spiel s4={&amp;t7,&amp;t8,1,2};
  68. Spiel s5={&amp;t4,&amp;t1,3,0};
  69. Spiel s6={&amp;t8,&amp;t5,2,0};
  70. Spiel s7={&amp;t1,&amp;t5,2,1};
  71. Spiel s8={&amp;t4,&amp;t8,7,5};
  72. Team* ptr_team[8];
  73. ptr_team[0] = &amp;t1;
  74. ptr_team[1] = &amp;t2;
  75. ptr_team[2] = &amp;t3;
  76. ptr_team[3] = &amp;t4;
  77. ptr_team[4] = &amp;t5;
  78. ptr_team[5] = &amp;t6;
  79. ptr_team[6] = &amp;t7;
  80. ptr_team[7] = &amp;t8;
  81. ergebnis_eintragen(s1);
  82. ergebnis_eintragen(s2);
  83. ergebnis_eintragen(s3);
  84. ergebnis_eintragen(s4);
  85. ergebnis_eintragen(s5);
  86. ergebnis_eintragen(s6);
  87. ergebnis_eintragen(s7);
  88. ergebnis_eintragen(s8);
  89. ausgabe(&amp;ptr_team[0]);
  90. }

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

答案1

得分: 1

In the for loop:

在这个for循环中:

  1. for (int i=0;i&lt;8;i++)
  2. {
  3. 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时,像这样的表达式:

  1. 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:

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

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

Also it seems in this if statement:

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

  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)

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

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

  1. 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就足够了。

  1. do
  2. {
  3. //...
  4. } while ( vertauscht);

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

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

You could declare your function like:

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

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

and call it like:

并且像这样调用它:

  1. ausgabe( ptr_team, 8 );

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

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

  1. 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

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

when i is equal to 7 then expressions like this

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

access memory outside the array ptr_team defined in main.

You could write your loop like for example

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

Also it seems in this if statement

  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)

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

  1. 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

  1. do
  2. {
  3. //...
  4. } while ( vertauscht);

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

You could declare your function like

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

and call it at least like

  1. ausgabe( ptr_team, 8 );

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

  1. 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:

确定