Definierte Elemente im array



  • Hallo,

    habe eine Frage zu folgender Aufgabe:
    http://s14.directupload.net/images/140212/exu39h4t.jpg

    Elemente definiert im Feld T=?
    Elemente definiert im Feld A=?

    Was versteht man unter definierten Elementen? Ich würde sagen im Feld T sind 16 Elemente definiert, und im Feld A 0.
    Jemand andere Meinungen und vllt. erklärungen?

    Vielen Dank schonmal für Eure Hilfe



  • Ich denke, in A sind genausoviel Elemente definiert, die werden doch in der Schleife alle gesetzt.



  • toby920 schrieb:

    Was versteht man unter definierten Elementen? Ich würde sagen im Feld T sind 16 Elemente definiert, und im Feld A 0.

    Okay: auf den offensichtlichen Trick mit der Nullterminierung bist Du nicht reingefallen.
    Trotzdem bin ich der Meinung, dass in T 50 Elemente definiert sind. Unter "definiert" verstehe ich, dass Du eine Begründete Aussage über deren Wert machen kannst - rein vom Anschauen des Sources.

    Meiner Aussage liegt zugrunde das T Platz für 50 Zeichen hat aber mit einem kürzeren string literal initialisiert wird. C garantiert Dir, dass die restlichen Werte in T dann auch definiert werden - mit 0 in diesem Fall.

    Deine Frage nach A kann ich nicht einordnen: hast Du den Code mal laufen lassen? Das wäre doch das erste, was ich täte - lange bevor ich in einem Forum fragte.



  • Furble Wurble schrieb:

    C garantiert Dir, dass die restlichen Werte in T dann auch definiert werden - mit 0 in diesem Fall.

    Wenn das stimmt, dann sind in der Tat 50 in T und 16 in A definiert ...



  • Ich würde sagen, dass in beiden Feldern 50 Elemente definiert sind, da für jeweils 50 Elemente Speicher reserviert wird.



  • MatzeHHC schrieb:

    Ich würde sagen, dass in beiden Feldern 50 Elemente definiert sind, da für jeweils 50 Elemente Speicher reserviert wird.

    Aber Du kannst nur unter bestimmten Bedingungen Aussagen über den Inhalt der 50 Elemente machen.

    Der Aufgabensteller schludert leider etwas bei der Aufgabenstellung ("You had one job!").

    Z.B. sind im folgenden beide Arrays komplett unterschiedliche paar Schuhe, wenn Ihr Euch den Inhalt anseht:[code0"c"]char A[50];

    void f(){
    char A[50];
    }[/code]


  • Mod

    Eigentlich meint man mit "definiert" im C-Jargon ja, dass für ein Datenobjekt Speicher reserviert wird:

    C-Standard, 3.5 schrieb:

    A declaration specifies the interpretation and attributes of a set
    of identifiers. A declaration that also causes storage to be reserved
    for an object or function named by an identifier is a definition.

    Hier würde ich aus dem Zusammenhang der Aufgabe eher davon ausgehen, dass der Wert des Objekts "definiert" sein soll, etwas, was man im C-Jargon eher "initialisiert" nennen würde. Vielleicht ist der Lehrer auch ein ganz fieser, der einen damit herein legen möchte und er meint tatsächlich die eigentliche Bedeutung des Wortes "definiert", anstatt die, die hier von der Aufgabenstellung impliziert wird. Man kann ja beide Antworten geben, um ganz sicher zu sein.



  • Furble Wurble schrieb:

    Deine Frage nach A kann ich nicht einordnen: hast Du den Code mal laufen lassen? Das wäre doch das erste, was ich täte - lange bevor ich in einem Forum fragte.

    Habe ich natürlich gemacht, im Feld T bekomme ich "schwere Klausur" als Ausgabe, im Feld A nichts, VOR dem Ablauf des Programms.
    Nach dem Ablauf steht in T immernoch "schwere Klausur" und in A "SCHWERE KLAUSUR" (in der Aufgabe ist ein kleiner Fehler, die 0x32 soll ein dezimal und kein Hexa wert sein).
    Aus der Aufgabe raus sieht man leider nicht ob er die definierten Felder vor oder nach dem Ablauf des Programms wissen möchte.

    Als Musterlösung (leider nicht vom Aufgabensteller) habe ich als Lösung, dass beide mit 50 definiert sind, allerdings erscheint mir das nicht logisch



  • Definiert in diesem Zusammenhang ist, dass die Elemente einen definierten Wert (im Gegensatz zu einem zufaelligen/beliebigen Wert) besitzen.

    Beispiel zum Unterschied Variablen/Funktionsdefinition zu definierte Werte: Zwar sind die Variablen definiert, trotzdem handelt sich um "undefined behaivour", da die Werte eben undefiniert sind.

    int a;
    int b;
    
    int res = a + b;
    

    Meiner Aussage liegt zugrunde das T Platz für 50 Zeichen hat aber mit einem kürzeren string literal initialisiert wird. C garantiert Dir, dass die restlichen Werte in T dann auch definiert werden - mit 0 in diesem Fall.

    Du darfst gern einen Verweis/Referenz im Standard zur Untermauerung nennen.


  • Mod

    knivil schrieb:

    Beispiel zum Unterschied Variablen/Funktionsdefinition zu definierte Werte: Zwar sind die Variablen definiert, trotzdem handelt sich um "undefined behaivour", da die Werte eben undefiniert sind.

    int a;
    int b;
    
    int res = a + b;
    

    Nicht die Werte sind hier undefiniert, sondern das ganze Verhalten. Praktisch heißt das zwar oft, dass die Variablen keinen definierten Wert haben, aber es kann eben auch die Festplattenformatierung dabei raus kommen.



  • Zwar sind die Variablen definiert, trotzdem handelt sich um "undefined behaivour", da die Werte eben undefiniert sind.

    selfquote 4tw: In dem Satz stelle ich 3 verschiedene "definiert" gegenueber: Syntax, Verhalten und Wert. Die Frage ist nun, welches davon vom Aufgabensteller gemeint ist. Undefiniertes Verhalten eher nicht, bleiben also 2 Moeglichkeiten uebrig. Weiterhin denke ich nicht, dass es um Syntax geht.

    Nicht die Werte sind hier undefiniert

    Ich wuerde schon sagen, dass die Werte (sofern sie nicht im Datensegment) undefiniert sind. Synonym koennte ich auch nicht-initialisiert sagen und ist klar verschieden von zufaellig oder beliebig.



  • toby920 schrieb:

    Aus der Aufgabe raus sieht man leider nicht ob er die definierten Felder vor oder nach dem Ablauf des Programms wissen möchte.

    Ich verstehe die Aufgabe so, dass der Zustand nach Programmlauf gefragt ist.



  • toby920 schrieb:

    Als Musterlösung (leider nicht vom Aufgabensteller) habe ich als Lösung, dass beide mit 50 definiert sind, allerdings erscheint mir das nicht logisch

    Würde ich mir jetzt keinen Kopf drum machen, ob jetzt 50 u. 16, oder beide 50 - inner Klausur könnte man fragen, so bleibt ein Risiko sich festzulegen.

    Nur das T 16 Elemente hat, halte ich als richtige Antwort für ausgeschlossen - mit obiger Begründung.



  • Nur das T 16 Elemente hat, halte ich als richtige Antwort für ausgeschlossen - mit obiger Begründung.

    Das T 16 definierte Elemente hat, halte ich als erwartete Antwort des Dozenten fuer moeglich.


  • Mod

    knivil schrieb:

    Nicht die Werte sind hier undefiniert

    Ich wuerde schon sagen, dass die Werte (sofern sie nicht im Datensegment) undefiniert sind. Synonym koennte ich auch nicht-initialisiert sagen und ist klar verschieden von zufaellig oder beliebig.

    Nein, eben nicht. Der Unterschied ist wichtig, deswegen würde ich hier auf genauer Unterscheidung bestehen. Es wäre für ein Programm, welches auf uninitialisierte Werte zugreift durchaus ein korrektes Verhalten, dass etwas ganz anderes passiert, als dass man einen undefinierten Wert erhält. Möglicherweise wird den Variablen (trotz vorheriger Definition) gar kein wirklicher Speicherplatz im Programm zugewiesen. Undefiniertes Verhalten ist etwas anderes als uninitialisierte (undefinierte) Werte.



  • Es wäre für ein Programm, welches auf uninitialisierte Werte zugreift durchaus ein korrektes Verhalten

    Gemaess http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html "Use of an uninitialized variable" eben nicht.

    [... undefinierten Wert] erhält

    Ich habe nicht gesagt/gemeint, dass man einen undefinierten Wert erhaelt. Ich habe gesagt/gemeint, dass die Benutzung von Variablendefinitionen mit nicht-initialisierten Werten undefiniert ist. Vielleicht ist der Rueckgabewert der Addition etwas missverstaendlich, hier die korrigierte Version:

    int a;
    int b;
    a + b;
    


  • Nicht die Werte sind hier undefiniert, sondern das ganze Verhalten. Praktisch heißt das zwar oft, dass die Variablen keinen definierten Wert haben, aber es kann eben auch die Festplattenformatierung dabei raus kommen.

    Wie das? Also schon klar, Festplattenformatierung ist jetzt wohl worst case, aber *unwissend_an* normal dürfte doch nur das ergebnis irgendeinen Mist enthalten?? *unwissend_aus*
    ??



  • Du hast ein falsches Bild von undefined behaviour. Hier: http://blog.regehr.org/archives/213 oder http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html. Aber normalerweise wird deine Festplatte nicht formatiert. Wichtig dabei: Das ganze Programm ist bedeutungslos, nicht erst, wenn die ensprechende Stelle im Code erreicht wird.


  • Mod

    beginner_offl schrieb:

    Wie das? Also schon klar, Festplattenformatierung ist jetzt wohl worst case, aber *unwissend_an* normal dürfte doch nur das ergebnis irgendeinen Mist enthalten?? *unwissend_aus*
    ??

    Weil du meinen speziellen, aber standardkonformen, Compiler benutzt hast, der einen Wrapper um jeden Speicherzugriff in den Code einbaut, der solche Situationen erkennt und im Falle von Zugriffen auf uninitialisierte Werte die Festplatte formatiert.

    Oder vielleicht etwas weniger an den Haaren herbei gezogen: Durch den fehlerhaften Zugriff werden im Programm unvorhergesehen Werte verändert, daher geht der spätere Call an die auf-den-Bildschirm-schreiben-Funktion des Betriebssystems fälschlicherweise an die die-Festplatte-ungefragt-formatieren-Funktion des Betriebssystems.

    P.S.: Das sind natürlich beides keine realistischen Szenarien, also keine Angst 🙂 . Aber es soll klar machen, dass es eben nicht so einfach ist, dass man nur einen falschen Wert erhält. Optimierter Maschinencode arbeitet nicht mehr auf der Vorstellungsebene einer Hochsprache wie C mit Variablen, Funktionen und Anweisungen. Für den Uneingeweihten ist das praktisch ein großes Kuddelmuddel, selbst die Trennung zwischen Daten und Code ist unklar. Daher kann so ziemlich alles mögliche die Folge sein, wenn etwas undefiniertes passiert. Wobei das "Mögliche" dann in den meisten Fällen doch eher harmlos ist und nur dein Programm kaputt macht (aber eben nicht unbedingt "nur" durch einen falschen Wert). Aber vielleicht wird dein Programm ja auch so verändert, dass es das Pentagon hackt und die Raketen abfeuert.

    P.P.S.: Der Link von knivil beschreibt sehr passend deine Frage und meine Antwort im ersten Satz, daher zitiere ich es nochmal explizit:

    Will a real compiler emit code to chomp your disk? Of course not, but keep in mind that practically speaking, undefined behavior often does lead to Bad Things because many security vulnerabilities start out as memory or integer operations that have undefined behavior. For example, accessing an out of bounds array element is a key part of the canonical stack smashing attack. In summary: the compiler does not need to emit code to format your disk. Rather, following the OOB array access your computer will begin executing exploit code, and that code is what will format your disk.



  • Ok, leuchtet ein.

    Aber vielleicht wird dein Programm ja auch so verändert, dass es das Pentagon hackt und die Raketen abfeuert.

    Sollte ich mal sicherheitshalber vor jedem "Kompilieren und Ausführen" mal den Quellcode an die NSA senden, falls sie ihn noch nicht haben ? 😉 😃


Log in to reply