Forum: PC-Programmierung Fehlermeldung Zugriffsverletzung, aber wo?


von dulli (Gast)


Lesenswert?

hallo miteinander,

beim debuggen wird mir angezeigt, dass ich eine Zugriffsverletzung habe, 
weiß aber nicht, was genau falsch sein soll. hoffe ihr könnt mir helfen.


---------------------------------------------------------------
void sortieren(int *zahlen, int anzahl){
  int tausch;



  for (int k = 1; k <= anzahl - 1; k++){
    for (int i = anzahl; i <= k+1; i--){
      if (zahlen[i] < zahlen[i - 1]){
        tausch = zahlen[k];
        zahlen[i] = zahlen[i - 1];
        zahlen[i - 1] = tausch;
      }
    }
  }

  printf("Zahlen in aufsteigender Reihenfolge:\n\n");
  for (int z = 1; z <= anzahl; z++){
    printf("%d ", zahlen[z]);
  }
  printf("\n");

}

int main()
{
  int anzahl;
  int *zahlen;
  int auswahl;


  printf("Wie viele Zahlen wollen sie bearbeiten?\n");
  scanf("%d", &anzahl);
  fflush(stdin);

  zahlen = (int*)malloc((anzahl) * sizeof(int));

  for (int i = 1; i <= anzahl; i++){
    printf("Zahl[%d]:",i);
    scanf("%d", &zahlen[i]);
    fflush(stdin);
  }


     sortieren(zahlen, anzahl);
     system("pause");
     return 0;


-----------------------------------------------------------------

von Peter II (Gast)


Lesenswert?

1
for (int i = 1; i <= anzahl; i++){
2
    scanf("%d", &zahlen[i]);
3
}

ein Array geht von 0 bis ... und nicht von 1 bis ...

von dulli (Gast)


Lesenswert?

Gibt es eine Möglichkeit, dass ich die speicherreservierung anpass um 
das feld bei 1 starten zu lassen?

von Peter II (Gast)


Lesenswert?

dulli schrieb:
> Gibt es eine Möglichkeit, dass ich die speicherreservierung anpass um
> das feld bei 1 starten zu lassen?

klar, einfach ein element mehr anfordern. Aber sinnvoll ist das nicht. 
Wenn man schon C Programmiert sollte man sich auch an gewisse Grundlagen 
halten.

Auch sollte eine Funktion "sortieren" keine Ausgaben machen.

von Kai S. (zigzeg)


Lesenswert?

dulli schrieb:
> for (int i = anzahl; i <= k+1; i--){
>       if (zahlen[i] < zahlen[i - 1]){

1. i startet mit "anzahl", aber auf "zahlen[anzahl]" (naechste Zeile) 
darf nicht zugegriffen werden => Zugriffverletzung schon in der ersten 
Iteration.

2. Bedingung ist "i <= k+1" ("solange gilt"), aber i wird dekrementiert 
=> keine Abbruchbedigung. Die Schleife laeuft also endlos, bzw. bis die 
zahl i unterlaeuft, d.h. kleiner wird als die kleinste negative Zahl 
(dann wird sie zur groessten positiven Zahl).

dulli schrieb:
> fflush(stdin);

Hm, soweit ich weiss kann man nur Ausgaben flush()en. Eine flush() der 
Eingabe muesste den Benutzer in den Hintern treten damit er "jetzt alles 
zuende tippt, was er schon im Kopf (Buffer) hat".

Was versuchst Du damit zu erreichen ?


ZigZeg

von dulli (Gast)


Lesenswert?

ok danke!

Jetzt habe ich aber, dass problem, dass mein bubble sort nicht 
funktioniert (ich will, dass die zweite if-schleife runterzählt):


void sortieren(int *zahlen, int anzahl){
  int tausch;



  for (int k = 0; k < anzahl - 1; k++){
    for (int i = anzahl-1; i > k+1; i--){
      if (zahlen[i] < zahlen[i - 1]){
        tausch = zahlen[k];
        zahlen[i] = zahlen[i - 1];
        zahlen[i - 1] = tausch;
      }
    }
  }

  printf("Zahlen in aufsteigender Reihenfolge:\n\n");
  for (int z = 0; z < anzahl; z++){
    printf("%d ", zahlen[z]);
  }
  printf("\n");

}



int main()
{
  int anzahl;
  int *zahlen;
  int auswahl;

  printf("Wie viele Zahlen wollen sie bearbeiten?\n");
  scanf("%d", &anzahl);
  fflush(stdin);

  zahlen = (int*)malloc((anzahl+1) * sizeof(int));

  for (int i = 0; i < anzahl; i++){
    printf("Zahl[%d]:",i);
    scanf("%d", &zahlen[i]);
    fflush(stdin);
  }

  system("pause");
  return 0;
}

von Klaus W. (mfgkw)


Lesenswert?

dulli schrieb:
> Gibt es eine Möglichkeit, dass ich die speicherreservierung anpass um
> das feld bei 1 starten zu lassen?

Ja, mit etwas Klimmzügen geht es.
1
  int          zahlen_tmp[10];        // hat 10 Elemente von [0] bis [9]
2
  int  * const zahlen = zahlen_tmp-1; // dieselben 10 Elemente, aber indiziert
3
                                      // von [1] bis [10]
4
5
  zahlen[1]  = 111;                   // meint eigentlich zahlen_tmp[0]
6
  zahlen[10] = 999;                   // meint eigentlich zahlen_tmp[9]

Peter II schrieb:
> klar, einfach ein element mehr anfordern.

siehe oben..

> Aber sinnvoll ist das nicht.


Es kann sinnvoll sei. Aber selten, und hier auch nicht unbedingt.

> Wenn man schon C Programmiert sollte man sich auch an gewisse Grundlagen
> halten.

Richtig. Es sei denn, es gibt im Einzelfall gute Gründe dagegen :-)

von Peter II (Gast)


Lesenswert?

dulli schrieb:
> Jetzt habe ich aber, dass problem, dass mein bubble sort nicht
> funktioniert (ich will, dass die zweite if-schleife runterzählt):

dann bau dir doch ein paar ausgaben ein oder debugge schritt für 
schritt. Das Programm ist doch recht klein. Debuggen und Fehlersuche 
gehört zu entwickeln dazu.

von Kai S. (zigzeg)


Lesenswert?

Ein Tippfehler ! Entweder Debuggen, oder nochmal gruendlich (!) 
durchlesen, wirst Du schon finden !

ZigZeg

von dulli (Gast)


Lesenswert?

habs gefunden, danke

von A. H. (ah8)


Lesenswert?

Bubblesort gilt eigentlich als wenig effizientes Sortierverfahren. Es 
ist am ehesten dann effizient einsetzbar, wenn die Daten bereits gut 
vorsortiert sind, also wenn die Elemente eines Feldes nur um wenige 
Positionen verschoben werden müssen. Dann kann Bubblesort den Umstand 
nutzen, dass nur einige wenige Durchläufe notwendig sind, um alle 
Elemente richtig zu platzieren. Findet während eines Durchlaufs kein 
Austausch mehr statt, so wir auch in den folgenden Durchläufen nichts 
mehr zu tun sein und der Vorgang kann abgebrochen werden. Genau diesen 
Vorteil nutzt Deine Implementierung aber nicht. Sie iteriert unbeirrt 
anzahl-1 mal über das Feld, selbst wenn das Feld längst sortiert ist. 
Das würde ich noch verbessern, selbst (oder gerade) wenn es nur eine 
Übung ist, denn nur dann kann Bubblesort seine Stärke wirklich 
ausspielen.

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Kai S. schrieb:
> dulli schrieb:
>> fflush(stdin);
>
> Hm, soweit ich weiss kann man nur Ausgaben flush()en.

Ja, richtig. Einen Input-Stream zu flushen ergibt keinen Sinn, deshalb 
ist es in C eigentlich verboten.

von Rainer V. (rudi994)


Lesenswert?

Zum Thema "Zweckentfremdung von fflush() nach scanf()" siehe auch hier:
Beitrag "scanf in C drei Zeichen einlesen"

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.