Wir lernen in der Schule das programmieren mit C++, unsere Lehrkraft meinte, das verwenden von globalen Variablen ist schlecht, weil der reservierte Speicherbereich nach Programm-Ausführung nicht wieder freigegeben wird. Ist dies korrekt? Ich bin bisher davon ausgegangen, dass das Betriebsystem (Windows) den reservierten Speicherbereich wieder frei gibt, wenn die Programm-Ausführung beendet wurde.
Milo schrieb: > Ich bin bisher davon ausgegangen, dass das > Betriebsystem (Windows) den reservierten Speicherbereich wieder frei > gibt, wenn die Programm-Ausführung beendet wurde. Natürlich. Wenn ein Programm beendet wird, wird der Speicher für das nävhste verwendet.
Probiere es doch einfach aus. Schreibe ein Programm, mit einer sehr großen globalen Variable und führe es mehrfach aus. Wenn der PC abstürzt, hat dein Lehrer wohl recht.
Milo schrieb: > das verwenden von globalen Variablen ist schlecht Abgesehen davon: Das ist in vielen Fällen sogar richtig. Viele Fälle von globalen Variablen sind tatsächlich schlecht. Aber die Begründung mit dem verbrauchten Speicher ist absolut falsch.
Milo schrieb: > Wir lernen in der Schule das programmieren mit C++, unsere Lehrkraft > meinte, das verwenden von globalen Variablen ist schlecht, weil der > reservierte Speicherbereich nach Programm-Ausführung nicht wieder > freigegeben wird. Das ist schlecht erklärt oder falsch verstanden. Globale Variablen werden statisch allokiert und verbrauchen also ihren Speicherplatz die ganze Zeit die ein Programm läuft. Lokale Variablen werden dynamisch allokiert und ihr Speicherplatz wird nach Beendigung der Prozedur oder Funktion, in der sie definiert sind, wieder freigegeben. LG, Sebastian
Klaus W. schrieb: > Aber die Begründung mit dem verbrauchten Speicher ist absolut falsch. Für die üblichen Betriebssysteme haste recht, das normal mit new/malloc-allokierte Zeug sollte dann weg sein. Aber auch bei Windows muss nicht unbedingt jeder Speicher nach Prozessende freigegeben sein, Stichwort IPC/SharedMemory. Kann man aber gerne als Spezialfall bzw. bewusst getroffene Entwurfsentscheidung sehen, sowas zu nutzen.
Eher ist interessant, in welcher Reihenfolge bei globalen Objekten von Klassen die Konstruktoren aufgerufen werden :)
Milo schrieb: > ... weil der reservierte Speicherbereich nach Programm-Ausführung > nicht wieder freigegeben wird. Ersetze "Programm-Ausführung" durch "Unterprogrammausführung". Dann passt es.
tut nix zur Sache schrieb: > Aber auch bei Windows muss nicht unbedingt jeder Speicher nach > Prozessende freigegeben sein, Stichwort IPC/SharedMemory. Ja klar. Aber nachdem der letzte Prozeß, der einen shared memory-Bereich nutzt, beendet ist, wird der auch freigegeben. Sogar unter Windows. Die Frage war aber nach globalen Variablen.
:
Bearbeitet durch User
Sebastian W. schrieb: > Das ist schlecht erklärt oder falsch verstanden. Dann hat die Lehrkraft das selbst falsch verstanden, ich habe meinen Kenntnisstand ebenfalls im Unterricht geäußert und mir wurde die Antwort gegeben, dass es nicht der Fall wäre, dass das Betriebssystem den Speicher freiräumt, sondern der Speicherplatz der globalen Variablen bis zum Neustart des Rechners nicht mehr für andere Anwendungen zur Verfügung steht.
Dann eher Leerkraft, würde ich sagen.
Milo schrieb: > und mir wurde die Antwort gegeben, dass es nicht der Fall wäre, dass das > Betriebssystem den Speicher freiräumt, Das ist völliger Quatsch. Jedes Programm hat globale Variablen, denn die C- bzw. C++-Standard Library definiert auch welche (z.B. die errno-Variable). Da man globale Variablen nicht freigeben kann, würden die ja permanent Speicher belegen. Es wäre auch eine ziemliche Sicherheitslücke, wenn Programme den Speicher so vollmüllen könnten. String-Literale und sonstige Konstanten werden genau wie globale Variablen im Speicher hinterlegt, typischerweise aber nochmal getrennt (schreibgeschützt). Würden die wie globale Variablen auch im Speicher bleiben, wäre das ziemlich mies! Globale Variablen haben zwar gewisse Probleme, aber wenn sie "const" sind und idealerweise auch "static", sind sie okay. Größere Blöcke an konstanten Daten kann man auch nur so sinnvoll hinterlegen (z.B. Grafiken, Kennlinien). Windows hat da zwar noch einen anderen Mechanismus für, aber andere Systeme nicht. Aus Sicht des Betriebssystems sind die unterschiedlichen Speichertypen des Programms alles das gleiche, einfach nur Teile eines linearen Adressraums. Einzelne Variablen kann das Betriebssystem sowieso nicht "sehen". Der Speicher eines Programms wird am Stück oder zerteilt in den RAM gelegt. Das Betriebssystem gibt diesen gesamten Bereich wieder frei nach Beenden des Programms, völlig egal ob da jetzt Stack, dynamisch allokierte Variablen oder globale Variablen drin sind. Dem Betriebssystem wäre es sogar egal wenn das Programm eine völlig andere Art der Speicherverwaltung nutzt. Klaus W. schrieb: > Dann eher Leerkraft, würde ich sagen Leider gar nicht so selten. Ich hatte einen Professor, der in einer Vorlesung über Linux-Kernel-Entwicklung behauptet hat, es gäbe keinen virtuellen Speicher und alle Programme würden sich den selben Bereich teilen. Nicht der gleiche Unsinn, aber artverwandt. Insbesondere Leerpersonal scheint in solchen Bereichen besonders gut Bescheid zu wissen...
wie du siehst, "scheinst" du recht zu haben. Die Frage wäre also: a) woher hat dein Lehrer seine Meinung und b) was bräuchte es, ihn von etwas anderem zu überzugen?
c) welches gute Buch liest man stattdessen?
k.A. schrieb: > wie du siehst, "scheinst" du recht zu haben. Die Frage wäre also: > a) woher hat dein Lehrer seine Meinung und > b) was bräuchte es, ihn von etwas anderem zu überzugen? Die Lehrkraft ist ehemals Software-Entwickler gewesen, unterrichtet aber den Großteil des Berufslebens Informationstechnik, ich habe es nicht notwendig die Lehrkraft von etwas zu überzeugen, davon wird die Note 1 auch nicht besser. Es ging mir ums Verständnis, ich habe in einer Prüfung Punktabzug bekommen, weil ich meine Variablen vor main() deklariert habe. Lehrkräfte sind auch nicht unfehlbar, hätte es eine Note ausgemacht, wäre ich natürlich eher dahinter, die Lehrkraft vom Gegenteil zu überzeugen, so geht es mir nur darum zu lernen und zu verstehen, statt es einfach ohne zu akzeptieren, ohne es Verstanden zu haben.
Softwerker schrieb: > Jedes Programm hat globale Variablen, denn die > C- bzw. C++-Standard Library definiert auch welche (z.B. die > errno-Variable). Das sollte eigentlich längst Geschichte sein (taucht aber immer wieder mal in einzelnen Funktionen als Problem auf -> *1). Anfänglich hat das zu heftigsten Problemen geführt als es üblich wurde Multi-Thread-Anwendungen zu erstellen und viele Funktionen solche Problem hatten. Wenn da nicht jede einzelne Instanz sauber ihren eigene Speicherbereich hat knallt es da ganz schnell. Static in Funktionen ist auch eine gute Methode hier fahler zu fabrizieren, wenn diese plötzlich von mehreren Threads benutzt wird. Gibt beides sehr lustige Effekte die ewig lange suchen kann, weil da immer nur gelegentlich mal ein paar Daten verfälscht werden. Die "errno" ist ein Sonderfall. Diese ist aus Anwendungssicht ja read only und das OS sorgt dafür das da immer nur der letzte Fehler drinsteht. Bei mehreren Threads muss das also garnicht mal mehr der Fehler sein der aufgetreten ist, sondern kann schon wieder eine anderer sein der wo anderes in der Zwischenzeit aufgetreten ist. Ist eher ein Relikt aus längst vergangen Tagen das meiner meinung nach mal bereinigt gehört. *1) Einge schöne Beispiele: "The function localtime may not be thread-safe.": - https://en.cppreference.com/w/c/chrono/localtime - https://en.cppreference.com/w/cpp/chrono/c/localtime "This function returns a pointer to static data and is not thread-safe" - https://en.cppreference.com/w/c/chrono/ctime - https://en.cppreference.com/w/cpp/chrono/c/ctime
Milo schrieb: > k.A. schrieb: > ich habe es nicht notwendig die Lehrkraft von etwas zu überzeugen, > davon wird die Note 1 auch nicht besser. > Lehrkräfte sind auch nicht unfehlbar, hätte es eine Note ausgemacht, > wäre ich natürlich eher dahinter, die Lehrkraft vom Gegenteil zu > überzeugen, so geht es mir nur darum zu lernen und zu verstehen, statt > es einfach ohne zu akzeptieren, ohne es Verstanden zu haben. Pragmatisch und intelligent. Hier nachzubohren hätte für dich keinen Vorteil (eher im Gegenteil).
Klaus W. schrieb: > Ja klar. > Aber nachdem der letzte Prozeß, der einen shared memory-Bereich nutzt, > beendet ist, wird der auch freigegeben. > Sogar unter Windows. > > Die Frage war aber nach globalen Variablen. Wollte bloß darauf hinaus, dass halt der Begriff '(Shared) global' bei eingefleischten Windows-Betriebssystem-Fans mitunter auch für Synchronisationsprimitive oder IPC genutzt werden kann. Und da kann's halt eben durchaus sein, dass die Exe aus dem Taskmgr weg ist, der Speicher aber noch von nem anderen Prozess in Verwendung (-> halt im Sinne von global). Egal. Für globale Variablen in einem Programm ist die Sache klar, das OS muss alles, was beim Start eines Prozesses angeschubst wird, auch wieder aufräumen, wenn der Prozess terminiert.
Milo schrieb: > Lehrkräfte sind auch nicht unfehlbar, hätte es eine Note ausgemacht, > wäre ich natürlich eher dahinter, die Lehrkraft vom Gegenteil zu > überzeugen Sehr pragmatisch, aber so ganz gutheißen kann ich das nicht; am Besten lernt man doch in einer direkten Diskussion und ggf. gemeinsamen Recherchieren/Ausprobieren. Es ist schade wenn Schüler/Studenten falsches einfach abnicken, aber natürlich auch bedenklich, wenn Lehrer unbeirrbar auf ihrer falschen Position beharren. Das habe ich auch oft genug erlebt. Aber es ist für niemanden eine Neuigkeit, dass es im Bildungssystem schon lange nicht mehr um das Lernen an sich geht...
Milo schrieb: > Punktabzug bekommen, weil ich meine Variablen vor main() deklariert > habe. Die Formulierung 'vor main' in diesem Zusammenhang macht mich stutzig.
A. S. schrieb: > Milo schrieb: >> Punktabzug bekommen, weil ich meine Variablen vor main() deklariert >> habe. > > Die Formulierung 'vor main' in diesem Zusammenhang macht mich stutzig. Die Formulierung ‚vor main’im Zusammenhang mit ‚global‘ macht für Variable eigentlich sehr viel Sinn. Oliver
Klaus W. schrieb: > Ja klar. > Aber nachdem der letzte Prozeß, der einen shared memory-Bereich nutzt, > beendet ist, wird der auch freigegeben. Schön wär's, System V Shared Memory ist da anderer Meinung.
Es gab vor 25 Jahren bestimmt noch mehr Probleme, die mit globalen Variablen genauso wenig zu tun haben.
Oliver S. schrieb: > Die Formulierung ‚vor main’im Zusammenhang mit ‚global‘ macht für > Variable eigentlich sehr viel Sinn. > > Oliver Eigentlich nicht. Wenn man nur mit einer C-Datei arbeitet, dann ist main meist ganz unten und die Funktionen darüber. Wenn da eine variable "vor main", also zwischen den Funktionen und main steht und nicht vorher declariert (oder es nur main gibt) dann ist diese Variable nur in main bekannt. Zwar wäre die Begründung dann immer noch falsch (was nicht passieren darf), der Punktabzug jedoch gerechtfertigt. Wie gesagt, ich wurde nur bei der Formulierung stutzig, es gibt ja keinen Kontext (welches Niveau z.B.). Üblicherweise sagt man "außerhalb von main" oder "extern". Wenn
A. S. schrieb: > Eigentlich nicht. Wenn man nur mit einer C-Datei arbeitet, dann ist main > meist ganz unten und die Funktionen darüber. Du überschätzt unser Niveau, der komplette Programmablauf findet in main() statt, vor main() waren nur die includes und eine Präprozessoranweisung und bei mir eben die Variablendeklarationen.
Milo schrieb: > Du überschätzt unser Niveau, der komplette Programmablauf findet in > main() statt Wenn es nur eine Funktion main() gibt und keine weitere Funktionen, dann sind globale Variablen tatsächlich überflüssig.
Frank M. schrieb: > Wenn es nur eine Funktion main() gibt und keine weitere Funktionen, dann > sind globale Variablen tatsächlich überflüssig. Dies bestreite ich auch nicht, ich habe nur die Begründung der Lehrkraft hinterfragt, weil es für mich unlogisch klang.
Das kannst Du recht einfach wiederlegen: 1. Kontrolliere den freien Systemspeicher und merke Dir die Größe. 2. Lege in einer Testsequenz eine sehr große Variable an. 3. Nutze sie auch indem Du irgendwas hineinschreibst. Wichtig! 4. Beende das Programm. 5. Kontrolliere den freien Systemspeicher erneut. Mit "große Variable" meine ich etwas, das nicht in der "Anzeige/Darstellung" verschütt gehen kann. Also richtig viele Megabyte oder sogar ein paar Gigadinger. Allerdings kleiner als 4G, da es da, je nach System (32 Bit), einige Eigenheiten geben kann. Ich habe mal, in grauer Vorzeit, gelernt, dass das System (Windoof, Linux usw.), den vom Programm reservierten "normalen" Speicher, beim Beenden des Programmes, wieder freigibt. Ist ja auch logisch, da oft viele Programme gestartet werden. Egal ob ein Programm vielfach gestartet wird oder viele verschiedene Programme nacheinander. Ist auch unabhängig von der Programmiersprache, da es ja vom System gemacht wird. Was aber wichtig ist: Das Programm muss regulär beendet werden denn erst dann wird "aufgeräumt". Die hellseherischen Fähigkeiten der meisten Betriebssysteme sind nämlich stark eingeschränkt. Eine Programmleiche behält meist, bis zu einem Neustart des Systems, ihre Ressourcen.
Irgend W. schrieb: > Die "errno" ist ein Sonderfall. Diese ist aus Anwendungssicht ja read only Nein, errno ist nicht read-only.
Sebastian S. schrieb: > Was aber wichtig ist: Das Programm muss regulär beendet werden denn erst > dann wird "aufgeräumt". Das ist Unsinn.
Klaus W. schrieb: > Natürlich. > Wenn ein Programm beendet wird, wird der Speicher für das nävhste > verwendet. Klar das machen unsichere Systeme so, damit man auch nach Programmende noch an dessen (geheime) Daten kommt. Klassisches Beispiel: image grabber beim Amiga.
Wenn es nur eine Methode in einem Programm gibt, ist egal, ob Variablen global oder lokal sind, weil die Programmlaufzeit gleich der Lebenszeit aller globalen und lokalen Variablen und Konstanten ist. Es könnte sein, dass der Compiler in beiden Fällen den gleichen Assembly-Code erzeugt. Globale Variablen sind nur suboptimal, wenn es mindestens eine weitere Funktion oder Methode in dem Programm gibt. Das wird die Lehrkraft zwar nicht überzeugen, weil Lehrkräfte die Weisheit mit dem Löffel gegessen haben und unfehlbar sind :) - Und zwar direkt nach ihrem Studienabschluss. (Ich hatte mal einen Lehrer, der hat tatsächlich argumentiert, dass er Recht habe, weil er das studiert hätte :) ) Der Speicher wird - wie bereits mehrfach beschrieben - vom Programm aus dem virtuellen Speicher alloziiert. Dazu wird der System-Call Malloc benutzt um vom Betriebssystemkernel den Speicher zugewiesen zu bekommen. Wird der Prozess beendet, wird sein Speicherbereich vom Betriebssystemkernel dealloziiert und steht anderen Prozessen zur Verfügung. Ausnahmsweise kann der Speicher von einem weiteren Prozess alloziiert sein (bei Inter-Prozess-Kommunikation). Dann wird der Kernel den natürlich erst freigeben, wenn beide Prozesse beendet sind.
Almdahl schrieb: > Dazu wird der System-Call Malloc > benutzt um vom Betriebssystemkernel den Speicher zugewiesen zu bekommen. malloc() ist kein Syscall, der dynamische Speicher wird von der C-Library verwaltet. Bei Bedarf(!) ruft sie den sbrk-Syscall auf, um mehr Speicher-Pages anzufordern.
Das stimmt offensichtlich - habe ich tatsächlich nicht gewusst und malloc für einen Syscall gehalten. Sorry für den Fehler.
Milo schrieb: > Frank M. schrieb: > >> Wenn es nur eine Funktion main() gibt und keine weitere Funktionen, dann >> sind globale Variablen tatsächlich überflüssig. > > Dies bestreite ich auch nicht, ich habe nur die Begründung der Lehrkraft > hinterfragt, weil es für mich unlogisch klang. Die Begründung ist natürlich Unsinn, das wurde Dir ja auch schon mehrfach bestätigt.
Sebastian S. schrieb: > Was aber wichtig ist: Das Programm muss regulär beendet werden denn erst > dann wird "aufgeräumt". Die hellseherischen Fähigkeiten der meisten > Betriebssysteme sind nämlich stark eingeschränkt. Eine Programmleiche > behält meist, bis zu einem Neustart des Systems, ihre Ressourcen. Wie das Programm beendet wird, spielt keine Rolle. Wichtig ist nur, dass es wirklich beendet wird, also der Prozess weg ist. Das Betriebssystem braucht auch keine hellseherischen Fähigkeiten, denn alle Ressourcen, die das Programm hat, hat es vorher vom Betriebssystem angefordert, daher weiß dieses sehr genau, was aufgeräumt werden muss. Irgend W. schrieb: > Anfänglich hat das zu heftigsten Problemen geführt als es üblich wurde > Multi-Thread-Anwendungen zu erstellen und viele Funktionen solche > Problem hatten. Wenn da nicht jede einzelne Instanz sauber ihren eigene > Speicherbereich hat knallt es da ganz schnell. Deshalb wurde thread-local storage erfunden. Damit kann man Variablen erstellen, die für jeden Thread separat sind, ohne dass man sich da weiter drum kümmern muss. > Die "errno" ist ein Sonderfall. Diese ist aus Anwendungssicht ja read > only Nein. Der C-Standard schreibt explizit vor, dass errno ein "modifiable lvalue" sein muss. Den kannst auch du jederzeit beschreiben, wenn du willst. > Bei mehreren Threads muss das also garnicht mal mehr der > Fehler sein der aufgetreten ist, sondern kann schon wieder eine anderer > sein der wo anderes in der Zwischenzeit aufgetreten ist. Ist eher ein > Relikt aus längst vergangen Tagen das meiner meinung nach mal bereinigt > gehört. Damit würdest du extrem viel bestehenden Code ungültig machen. Es gibt hier auch mehrere Lösungen mit dem bestehenden errno. Die eine ist die erwähnte thread-local storage. Eine andere ist, errno nicht als Variable zu implementieren, denn es ist Absicht, dass C nicht sagt, dass es eine Variable sein muss, sondern nur ein "modifiable lvalue". Das heißt, es ist auch so etwas erlaubt wie:
1 | #define errno *some_function()
|
Und tatsächlich steht genau sowas auf meinem Linux-System in /usr/include/errno.h drin:
1 | /* The error code set by various library functions. */
|
2 | extern int *__errno_location (void) __THROW __attribute_const__; |
3 | # define errno (*__errno_location ())
|
Rülpsende Bytes schrieb: > Klaus W. schrieb: > >> Natürlich. >> Wenn ein Programm beendet wird, wird der Speicher für das nävhste >> verwendet. > > Klar das machen unsichere Systeme so, damit man auch nach Programmende > noch an dessen (geheime) Daten kommt. Klassisches Beispiel: image > grabber beim Amiga. Auch sichere Systeme machen das. Sie nullen nur einfach den Speicher, bevor sie ihn dem anderen Programm zur Verfügung stellen. Almdahl schrieb: > Globale Variablen sind nur suboptimal, wenn es mindestens eine weitere > Funktion oder Methode in dem Programm gibt. Allerdings haben sie auch nur dann überhaupt einen Sinn.
Rolf M. schrieb: > Auch sichere Systeme machen das. Sie nullen nur einfach den Speicher, > bevor sie ihn dem anderen Programm zur Verfügung stellen. > > Almdahl schrieb: >> Globale Variablen sind nur suboptimal, wenn es mindestens eine weitere >> Funktion oder Methode in dem Programm gibt. > > Allerdings haben sie auch nur dann überhaupt einen Sinn. Aber nur solange wie die localen Objecte nicht die Stackgöße überschreiten.
1 | int main(int argc, const char *argv[]) |
2 | {
|
3 | char myarr[10000000]; |
4 | myarr[sizeof(myarr)-1]=22; |
5 | return 0; |
6 | }
|
zeigt einem schnell wo die Grenzen sind.
demo schrieb: > zeigt einem schnell wo die Grenzen sind. Ich weiss jetzt nicht, was du meinst 😇
1 | #include <stdio.h> |
2 | 2
|
3 | 3 #pragma comment(linker,"/stack:16777216") |
4 | 4
|
5 | 5 int main(int argc, const char *argv[]) |
6 | 6 { |
7 | 7 char myarr[10000000]; |
8 | 8 myarr[sizeof(myarr)-1]=22; |
9 | 9 printf("%d\n", myarr[sizeof(myarr)-1]); |
10 | 10 return 0; |
11 | 11 } |
Ja, das Verwenden globaler Variablen ist 'ne schlechte Idee, nein der Speicher bleibt nicht "kleben". Was stimmt, und Dein Lehrer vermutlich eigentlich ausdrücken wollte (will ihm ja nicht unterstellen dass er nicht weiß was er unterrichtet), ist, dass globale Variablen während der gesamten Laufzeit des Programmes allokiert bleiben (müssen). Wenn Du da 'ne Megabyte große Struktur rumkugeln hast, von der ein paar Tausend Instanzen (in einem Array beispielsweise) global durch die Gegend geworfen werden müssen, trägt das schon ein bissi auf im Arbeitsspeicher. Allerdings auch das nur so lang wie das Programm läuft. Globale Variablen sind aber aus einem anderen Grund schlecht, der Dir wahrscheinlich erst bewusst wird, wenn Du mit Unterprogrammen und Klassen zu tun bekommst. Sie sind global. Klingt auf den ersten Blick jetzt praktisch, weil dann kann man ja von überall drauf zugreifen. Ist, vom Sicherheitsaspekt mal ganz abgesehen, allerdings unhandlich wenn Du in diversen Unterprogrammen dann plötzlich anfangen müsstest, die Variablen umständlich zu benennen weil die "einfachen" Namen irgendwann ausgehen. Ausserdem... war jetzt counter1 die Zählvariable die ich verwenden kann, oder steht da in der anderen Routine was drin das ich noch brauch, war das in der Routine die die hier aufgerufen hat, oder war das ganz woanders, oder... Da werden die lokalen Variablen dann plötzlich aber SOWAS von praktisch!
> gegeben, dass es nicht der Fall wäre, dass das Betriebssystem den > Speicher freiräumt, sondern der Speicherplatz der globalen Variablen bis > zum Neustart des Rechners nicht mehr für andere Anwendungen zur > Verfügung steht. Von welchen Versionen von Windows war da die Rede? Für gewisse Werte von (alten) Windows' traf sowas tatsächlich und systematisch zu... (damals waren wir noch klein und die PCs gross, gelle?) SCNR
Von https://docs.microsoft.com/en-us/archive/msdn-magazine/2000/july/under-the-hood-happy-10th-anniversary-windows: If a Win16 application failed to clean up and exit properly, it wasn't uncommon to leave orphaned DLLs and global heap blocks. Even worse were unfreed USER and GDI resources, which came from two 64KB heaps. These small heaps gave rise to the free system resources problems, where their available space kept dropping until the only recourse was to reboot.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.