Kompiler Unterschiede?

Schnelle objektorientierte, kompilierende Programmiersprache.
namdlef
Beiträge: 10
Registriert: Sa Dez 17, 2011 10:58 pm

Kompiler Unterschiede?

Beitrag von namdlef » Sa Dez 17, 2011 11:28 pm

Hallo,

ich bin ganz neu hier, ich möchte nach längerer Abstinenz wieder meine C++ Kenntnisse ausbauen. Auf meinem Rechner programmiere ich mit Code::Blocks 10.05 mit Gnu GCC und Visual Studio 2008.
Auf einer Seite habe ich hier den Sortieralgorithmus Bubblesort entdeckt und bisschen rumexperimentiert. Dabei gibt es bei den Ausgaben nach dem Sortieren an einer Stelle einen Unterschied den ich mir einfach nicht erklären kann. Verursacht wird er durch die Funktion BubbleSort_normal(matrix,size); Aber hier erst einmal der Code.

Code: Alles auswählen

#include <iostream>
#include <time.h>

using namespace std;

// Prototypen
void BubbleSort_normal (int *values, int n);
void BubbleSort_verbessert(int *values, int n);
void BubbleSort_sehrgut(int *values, int n);
void array_ausgabe(int *values, int n);

void BubbleSort_normal(int *values, int n)
{

  int tmp;        // Hilfsvariable zum Vertauschen von Werten

  // durch das ganze Feld gehen
  for (int i = 0; i < n; i++)
  {
    // am Ende beginnen das kleinste Element zu suchen
    for (int j = n - 1; j >= i; j--)
    {
      // prüfen ob das Element kleiner als der Vorgänger ist
      if (values[j] < values[j - 1])
      {
        // Werte vertauschen
        tmp = values[j];
        values[j] = values[j - 1];
        values[j - 1] = tmp;
      }
    }
  }
}

void BubbleSort_verbessert(int *values, int n)
{

  int limit;         // limit: gibt den Index des ersten unsortierten Elements an
  int lastmove;       // lastmove: Index der letzten Vertauschung

  // beim ersten Durchlauf ist das Limit 1,
  // d.h. alle Elemente werden geprüft
  limit = 1;

  do
  {
    // es wurde noch nichts vertauscht

    lastmove = 0;

    // am Ende beginnend durch den unsortierten
    // Teil des Feldes gehen
    for (int i = n - 1; i >= limit; i--)
    {
      // Wert ist kleiner als der vorhergehende

      if (values[i] < values[i - 1])
      {
        // vertauschen

        int help = values[i];
        values[i] = values[i - 1];
        values[i - 1] = help;

        // Position der Änderung merken
        lastmove = i;
      }
    }

    // alle Elemente vor dem letzten Tausch sind bereits sortiert
    // deshalb können wir beim nächsten mal dort stoppen
    limit = lastmove + 1;

  // solange sortieren, bis nichts mehr geändert wird
  } while (lastmove != 0);
}

void BubbleSort_sehrgut(int *values, int n)
{


  int left,           // left: linker Ausgangspunkt, Startpunkt bei der Suche nach dem größten Element
                      //       Endpunkt bei der Suche nach dem kleinsten Element
      right,          // right: rechter Ausgangspunkt, Startpunkt bei der Suche nach dem kleinsten Element
                      //        Endpunkt bei der Suche nach dem größten Element
      lastmove;       // lastmove: speichert den Index der letzten Vertauschung

  // Anfang des Arrays
  left = 0;
  // Ende des Arrays
  right = n - 1;
  // die letzte Vertauschung auf die Anzahl setzen; wird nichts vertauscht wird sowohl left als auch right
  // lastmove und der Algorithmus bricht ab
  lastmove = n;

  int *vec = new int[n];
  int help;

  do
  {
    // von rechts nach links das kleinste Element suchen
    // und ganz nach links verschieben
    for (int i = right; i > left; i--)
    {
      // prüfen ob das Element kleiner als das vorhergehende ist

      if (vec[i] < vec[i - 1])
      {
        // vertauschen
        help = vec[i];
        vec[i] = vec[i - 1];
        vec[i - 1] = help;

        // Index der Vertauschung merken
        lastmove = i;
      }
    }

    // bis zur Vertauschung sind alle Elemente sortiert
    left = lastmove;

    // von links nach rechts das größte Element suchen
    // und ganz nach links verschieben
    for (int i = left; i < right; i++)
    {
      // prüfen ob das Element größer als das nachfolgende ist
      if (vec[i] > vec[i + 1])
      {
        // vertauschen
        help = vec[i];
        vec[i] = vec[i + 1];
        vec[i + 1] = help;

        // Index der Vertauschung merken
        lastmove = i;
      }
    }

    // nach der Vertauschung sind alle Elemente sortiert
    right = lastmove;

  // sortieren bis sich die sortierten Bereiche überschneiden oder nichts verändert wurde
  } while (left < right);

  // !!Heap Speicher wieder freigeben!!
  delete [] vec;
}


void array_ausgabe(int *values, int n)
{
	for (int i = 0; i < n; ++i)
	{
		cout << "i: " << i << " "<< values[i] << " " << endl;
	}

	cout << endl << endl;
}

int main()
{
    int matrix[] = { 23, 11, 28, 67, 3, 9, 71, 32, 3999 , 15 , 54, 982, 10333 };

	// die Anzahl der Elemente berechnen
    int size = sizeof(matrix) / sizeof(int);

	cout << endl << endl << size << " Elemente in matrix" << endl << endl;
	cout << "matrix vor der Sortierung: " << endl;

	array_ausgabe(matrix, size);


	BubbleSort_normal(matrix,size);

	//BubbleSort_verbessert(matrix, size);

	// BubbleSort_sehrgut(matrix, size);

	cout << "matrix nach der Sortierung: " << endl;

	array_ausgabe(matrix, size);

	return 0;
}
Und hier die Ausgaben:

Mit Code::Blocks gnu Compiler

matrix vor der Sortierung
i: 0 23
i: 1 11
i: 2 28
i: 3 67
i: 4 3
i: 5 9
i: 6 71
i: 7 32
i: 8 3999
i: 9 15
i: 10 54
i: 11 982
i: 12 10333
matrix nach der Sortierung
i: 0 9
i: 1 11
i: 2 15
i: 3 23
i: 4 28
i: 5 32
i: 6 54
i: 7 67
i: 8 71
i: 9 982
i: 10 3999
i: 11 10333
i: 12 4634440

Mit Visual Studio
matrix vor der Sortierung:
i: 0 23
i: 1 11
i: 2 28
i: 3 67
i: 4 3
i: 5 9
i: 6 71
i: 7 32
i: 8 3999
i: 9 15
i: 10 54
i: 11 982
i: 12 10333
matrix nach der Sortierung:
i: 0 3
i: 1 9
i: 2 11
i: 3 15
i: 4 23
i: 5 28
i: 6 32
i: 7 54
i: 8 67
i: 9 71
i: 10 982
i: 11 3999
i: 12 10333

Also der Gnu Compiler unterschlägt jeweils das kleinste Element und fügt statt dessen als letztes int Element einen undefinierten Wert ein.
Hat jemand eine Idee was hier für ein Fehler vorliegen könnte?

Viele Grüße aus Cottbus

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Kompiler Unterschiede?

Beitrag von cloidnerux » Sa Dez 17, 2011 11:55 pm

Hallo,
Hi und Willkommen im Forum.
ich bin ganz neu hier, ich möchte nach längerer Abstinenz wieder meine C++ Kenntnisse ausbauen.
Das ist gut und damit bist du hier richtig^^
Wenn du willst kannst du dich etwas genauer im Brett "Uservorstellung" vorstellen.
Auf einer Seite habe ich hier den Sortieralgorithmus Bubblesort entdeckt und bisschen rumexperimentiert. Dabei gibt es bei den Ausgaben nach dem Sortieren an einer Stelle einen Unterschied den ich mir einfach nicht erklären kann.
Normalerweise läuft Code nach dem C/C++-Standard in beiden Compilern gleich ab, nur verzeihen die Compiler unterschiedlich Fehler, bzw korrigieren sie eigenständig.
Daher würde ich nochmal genau nach Index-Fehlern suchen, ob du nicht vlt irgendwo einen Fehler in deinen Indices hast, z.B einen Negativen Index oder einen Index außerhalb des Bereichs.

MfG cloidnerux.
Redundanz macht wiederholen unnötig.
quod erat expectandum

namdlef
Beiträge: 10
Registriert: Sa Dez 17, 2011 10:58 pm

Re: Kompiler Unterschiede?

Beitrag von namdlef » So Dez 18, 2011 12:32 am

Wenn du willst kannst du dich etwas genauer im Brett "Uservorstellung" vorstellen.
Ja eigentlich ist das ja auch üblich in Foren. Das wird auf jeden Fall nachgeholt.
Daher würde ich nochmal genau nach Index-Fehlern suchen, ob du nicht vlt irgendwo einen Fehler in deinen Indices hast, z.B einen Negativen Index oder einen Index außerhalb des Bereichs.
Hmm ... na dazu müsste ich ersteinmal genau schauen wie in Code::Blocks der Debugger funktioniert. Ich werde mal schauen ob der auch so komfortabel ist wie der vom Visual Studio. :roll: :roll:

Vielen Dank erst einmal für die schnelle Antwort.

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Kompiler Unterschiede?

Beitrag von cloidnerux » So Dez 18, 2011 12:35 am

Hmm ... na dazu müsste ich ersteinmal genau schauen wie in Code::Blocks der Debugger funktioniert. Ich werde mal schauen ob der auch so komfortabel ist wie der vom Visual Studio.
Es würde wahrscheinlich reichen, die Indices per printf auszugeben, taucht irgendwo etwas kleiner 0 auf oder größer dem Maximum, ist das was falsch.
Vielen Dank erst einmal für die schnelle Antwort.
Kein Problem.
Redundanz macht wiederholen unnötig.
quod erat expectandum

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Kompiler Unterschiede?

Beitrag von Xin » So Dez 18, 2011 11:57 am

Ich habe gerade Win7 laufen und mir flott Code::Blocks mit GCC installiert.

Code: Alles auswählen

matrix vor der Sortierung:
i: 0 23
i: 1 11
i: 2 28
i: 3 67
i: 4 3
i: 5 9
i: 6 71
i: 7 32
i: 8 3999
i: 9 15
i: 10 54
i: 11 982
i: 12 10333


matrix nach der Sortierung:
i: 0 3
i: 1 9
i: 2 11
i: 3 15
i: 4 23
i: 5 28
i: 6 32
i: 7 54
i: 8 67
i: 9 71
i: 10 982
i: 11 3999
i: 12 10333
Was mache ich falsch, dass das Ergebnis richtig ist?


Ansonsten von mir auch ein Willkommen im Forum.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: Kompiler Unterschiede?

Beitrag von nufan » So Dez 18, 2011 1:24 pm

Xin hat geschrieben:Was mache ich falsch, dass das Ergebnis richtig ist?
Weil der Wert vor dem Array 0 ist und deshalb an seiner Stelle bleibt. Wenn du im Array negative Zahlen hast, wird die 0 auch in den Array aufgenommen.

Code: Alles auswählen

void array_ausgabe(int *values, int n)
{
   for (int i = -1; i < n; ++i)
   {
      cout << "i: " << i << " "<< values[i] << " " << endl;
   }

   cout << endl << endl;
}
Fügst du in main() noch argc und argv ein und setzt ein paar Parameter, bekommst du argc als Wert reingemischt. Wie das aber ohne Parameter geht, ist mir nicht ganz klar... Irgendwelche speziellen Debug-Einstellung?

Speicherstruktur auf meinem 64-bit Kubuntu ist hier zu sehen: http://www.proggen.org/forum/viewtopic.php?f=21&t=4748

EDIT: Natürlich nur argc, nicht argc+1.

namdlef
Beiträge: 10
Registriert: Sa Dez 17, 2011 10:58 pm

Re: Kompiler Unterschiede?

Beitrag von namdlef » So Dez 18, 2011 8:11 pm

Xin hat geschrieben:Ich habe gerade Win7 laufen und mir flott Code::Blocks mit GCC installiert.

Was mache ich falsch, dass das Ergebnis richtig ist?


Ansonsten von mir auch ein Willkommen im Forum.
Hallo,

hm ... gute Frage. Ich habe soeben auf einem anderen Rechner ebenfalls mit Win7 und Code::Blocks mit GCC das Programm laufen lassen und bekomme dort ebenso wie du das korrekte Ergebnis angezeigt.

Code: Alles auswählen

13 Elemente in matrix

matrix vor der Sortierung:
i: 0 23
i: 1 11
i: 2 28
i: 3 67
i: 4 3
i: 5 9
i: 6 71
i: 7 32
i: 8 3999
i: 9 15
i: 10 54
i: 11 982
i: 12 10333


matrix nach der Sortierung:
i: 0 3
i: 1 9
i: 2 11
i: 3 15
i: 4 23
i: 5 28
i: 6 32
i: 7 54
i: 8 67
i: 9 71
i: 10 982
i: 11 3999
i: 12 10333

Process returned 0 (0x0)   execution time : 0.065 s
Press any key to continue.

Ist schon bisschen eigenartig, aber ich danke euch dennoch für eure Bemühungen.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Kompiler Unterschiede?

Beitrag von Xin » Di Dez 20, 2011 11:22 am

namdlef hat geschrieben:Ich habe soeben auf einem anderen Rechner ebenfalls mit Win7 und Code::Blocks mit GCC das Programm laufen lassen und bekomme dort ebenso wie du das korrekte Ergebnis angezeigt.

Ist schon bisschen eigenartig, aber ich danke euch dennoch für eure Bemühungen.
Wo benutztest Du Code::Blocks zuvor?
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

namdlef
Beiträge: 10
Registriert: Sa Dez 17, 2011 10:58 pm

Re: Kompiler Unterschiede?

Beitrag von namdlef » Di Dez 20, 2011 7:02 pm

Xin hat geschrieben:Wo benutztest Du Code::Blocks zuvor?
Auf meinen schicken nagelneuen Sony Vaio. :P :P ... war nur Spaß.
Also ich hab hier mal einige Informationen zur Hardware. Vielleicht meinst du sowas in der Art?

Betriebssystemname Microsoft Windows 7 Home Premium
Version 6.1.7601 Service Pack 1 Build 7601

Systemhersteller Sony Corporation
Systemmodell VPCEH2N1E
Systemtyp x64-basierter PC
Prozessor Intel(R) Core(TM) i5-2430M CPU @ 2.40GHz, 2401 MHz, 2 Kern(e), 4 logische(r) Prozessor(en)
BIOS-Version/-Datum INSYDE R0180Z9, 28.04.2011
SMBIOS-Version 2.7

Installierter physikalischer Speicher (RAM) 4,00 GB

Gesamter realer Speicher 3,95 GB
Verfügbarer realer Speicher 2,52 GB
Gesamter virtueller Speicher 7,90 GB
Verfügbarer virtueller Speicher 5,78 GB
Größe der Auslagerungsdatei 3,95 GB
Auslagerungsdatei C:\pagefile.sys

----------------------------------------------------------------------
Ansonsten wie schon gesagt Code::Blocks 10.05 rev 6283
Compiler: GNU GCC

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Kompiler Unterschiede?

Beitrag von Xin » Di Dez 20, 2011 7:46 pm

namdlef hat geschrieben:
Xin hat geschrieben:Wo benutztest Du Code::Blocks zuvor?
Auf meinen schicken nagelneuen Sony Vaio. :P :P ... war nur Spaß.
Also ich hab hier mal einige Informationen zur Hardware. Vielleicht meinst du sowas in der Art?

Betriebssystemname Microsoft Windows 7 Home Premium
Version 6.1.7601 Service Pack 1 Build 7601

Ansonsten wie schon gesagt Code::Blocks 10.05 rev 6283
Compiler: GNU GCC
Windows als OS war, was mich interessierte. CodeBlocks kann man ja auch unter Linux nutzen. :-)

Dann ist es wirklich merkwürdig. Aber wenn Du keinen Fehler mehr mit dem Quelltext hast und ich keinen, dann ist das vielleicht nicht der Quelltext, der den Fehler ausgelöst hat.

Hast Du vielleicht beim Wechsel auf Visual Studio noch etwas geändert?
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Antworten