Low-low Level Struktur

#1

Moin, ich möchte mal von euch etwas wissen, was für mich sehr wichtig sei:

Wie trägt man folgende Struktur:

	int i1;
	int i2;
} Struktur;

char Array[Groesse];

Struktur * Zeiger = NULL;```
an einer Position x in das Array `Array` ein,

ohne [U]malloc und memcpy ?[/U]

Ich sitze seit mehreren Stunden dran, etwas stimmt nicht. Versucht hatte ich:

```Array = (Struktur *) (&Struktur + position);
Array->i1 = 0x10;
Array->i2 = 0x99;```
Das scheint echt Quatsch zu sein, weiß jmd. Rat oder gibt mir einen einfachen Link nach SOF? Vielen Dank für jede Antwort.
#2

Das Array vom Typ Struktur zu deklarieren war wohl zu einfach?

hier ist Dein <()><
ungetested
[spoiler]int i =0; int strukturLaenge = sizeof(Struktur); char [strukturLaenge] StrukturAsChar = (char *) &Struktur; for (i=0;i<strukturLaenge ;i++)[ Array[x+i] = StrukturAsChar **; }[/spoiler]

bye
TT

#3

Ok, DANKE.

Das char StrukturAsChar[] ist 1000000 Byte groß/lang.

Geht es kürzer?

Wieso muss mit & die Adresse geholt werden?

Darf ich “später” “->” zum Setzen benutzen?

Schreibst du mir ein KSKB fürs Schreiben an Position x, Zeiger auf x und Lesen von Position x?

Da wäre echt nett.

Was meinst mit du array of structures?

#4

@Timothy_Truckle , er sagt, die Initialisierung des Arrays StrukturAsChar sei ungültig.

aufgewendete Zeit ist ein paar Stündchen

Edit:
Versuchsaufbau:
[spoiler]``` typedef struct meine_struktur {
int i1;
int i2;
} meine_struktur;

char ein_array[1000000];
 
meine_struktur * meine_struktur_zeiger = NULL; /* Zeigt auf die bei pos in ein_array eingefügte meine_struktur. :S */```[/spoiler]
#5

push

#6

pop :twisted:

Du kannst die Pointer beliebig umbiegen, und kackfrech sagen: “Hier, der Speicher ist jetzt ein Array von (Pointer auf) Strukturen”

    typedef struct Struktur 
    {
        int i1;
        int i2;
    } Struktur;

    const size_t arraySize = 3 * sizeof(Struktur);
    char array[arraySize];
    memset(array, 0, arraySize);

    Struktur *struktur = reinterpret_cast<Struktur*>(array);
    struktur[0].i1 = 0x12345678;
    struktur[0].i2 = 0xAABBCCDD;

    for (size_t i = 0; i < arraySize; ++i)
    {
        std::cout << "At " << i << " found " << std::hex << int32_t(array**) << std::endl;
    }

Ausgabe:


At 0 found 78
At 1 found 56
At 2 found 34
At 3 found 12
At 4 found ffffffdd
At 5 found ffffffcc
At 6 found ffffffbb
At 7 found ffffffaa
At 8 found 0
At 9 found 0
At a found 0
At b found 0
...

Dass das ganze gerade bei Structs mit paddings und alignments usw. auch schiefgehen kann (insbesondere, wenn man sowas wie “int” verwendet, und nicht “int32_t”), sollte aber klar sein.

#7

Danke, bitte nur ein neuerer C Style, nicht k&r und ansi. Bitte nicht c++. Könntest du das “umbiegen”? (Auto-Korrektur macht daraus “Unruhen”).^^

#8

Dann ist das reinterpret_cast<Struktur*> ein (Struktur*), und das “cout” ist nur für’s testen, das in ein “printf” zu ändern sollte nicht das Problem sein.

#9

Hallo Marco, vielleicht noch wach und kannst mir etwas beantworten,

sagen wir, es gebe eine Struktur mit einem Zeiger auf den nächsten dieser Struktur, außerdem Variablen current, previous und next; iterierte man dann (richtigerweise) so durch diese Struktur (next könnte NULL sein):

		prev = curr;
		curr = curr->next;
		if (curr) {
			next = curr->next;
		}
	}```

?
#10

Sieht beim Überfliegen nicht “falsch” aus. Ob das “size” überhaupt benötigt wird, könnte man sich überlegen (der Test auf NULL sollte ja reichen…). Ausprobieren, printf’en, debuggen…!?

#11

Dass das ganze gerade bei Structs mit paddings und alignments usw. auch schiefgehen kann

Warum sollte das ?
der sizeof operator / funktion sollte das Padding berücksichtigen …
Du musst nur garantieren, das variable datentypen immer gleich sind, und das padding immer gleich ist. Und das ist es definitiv immer innerhalb gleicher Übersetzungseinheiten (exe/dll)
Wenn das serialisierst, also über Übersetzungseinheiten / prozessgrenzen hinweg daten austauschst, dann kann es natürlich zum problem werden.

iterierte man dann (richtigerweise) so durch diese Struktur (next könnte NULL sein)

Dir sollt rest mal klar werden wass genau du willst ^^

Arrays -> daten liegen hintereinander im speicher. Die größe des Speichers, bzw wie Anzahl der elemente wird expliziet gespeichert.
Du brauchst keinen next/provious zeiger, weil die Posi des nächsten elements immer durch Posi des aktuellen elements + elementsize oder generell Anfangspos + Index * elementsize berechnet werden kann.
Grosser nachteil, du musst die Max Anzahl der elemente vorher kennen, oder teueres umkopieren bei überschreiten in kauf nehmen …

verkettete Listen - die daten liegen nicht hintereinander im Speicher sondern irgendwo … auch die reihenfolge ist nicht definiert (5 kann weit vor 4 im Speicher liegen).
Dafür brauchst die kette von zeigern … Beim Anfügen von elementen musst also immer das vorherige(den zeiger drinnen) mit aktualisieren.
Vorteil ist, das keinen speicher am stueck allokieren musst, und daher auch nicht im vorraus wissen wieviel elemente es werden und anfügen immer recht zügig geht.

while (curr && curr->size < size)
hier sollte eine abfrage auf curr reichen ?
size am element zu speichern macht nur sinn, wenn die elemente in der liste wirklich unterschiedlich groß sind … ist das der Fall? (dann wird auch ne lösung mit nem array komplexer)
Aber bei ner liste solltest nie null elemente haben, sondern immer der zeiger sollte das ende repräsentieren …

Ciao …

#12

Hallo, Danke für eure Antworten. Ich hab mehrere Probleme.

Ich darf den kompletten Quelltext nicht posten. Ursprünglich hat ich dieses Thema unter Hausgaben gepostet. Ich hab mich an einer ‘Musterlösung’ versucht.

Es ist keine Ringliste o. Ä., es ist eine einfach verkettete Liste. Ich brauche den Vorgänger, aktuell und Nachfolger. Vorgänger kann NULL sein, Nachfolger kann NULL sein, aktuell ‘sollte eigentlich nichtNULL sein.

Ich hab keinen previous-Zeiger. Der Nachfolger des letzten Elem ist einfach NULL. curr->size (jetzt wird es spannend, size_t) kann irgendeine Größe/Länge habn.

Ich hab 1.000 Fälle zu berücksichtigen. Der User kann die Liste ‘kaputtmachen’. Kann es erkannt werden?, kann es wiederhergestellt werden? In Java wäre das einfacher und auch schonma geschrieben.

Auf sizeof muss ich mich verlassen, und das gibt auch die richtige Länge an, unter Windows etwas anderes Linux.

Virenscanner funkt mir dazwischen … Übersetzen Verbinden Linken, gut, das läuft, .exe Starten Prozess friert ein.

Summa: 1.000 Zeilen geschrieben, einmal deleten, alles neuschreiben, es läuft; aber auf einmal greife ich auf einen Speicherbereich außerhalb von ein_array zu…

#13

@CyborgBeta , könntest du dir vielleicht diesen Hinweis zu rate nehmen

und dann eine verständliche Frage stellen was du denn nun Wissen willst, handelt es sich nun um ein Array? scheinbar nicht da du ja selbst von einer verketteten Liste redest. Aus deiner Antwort um 12:53 wird man dafür kein Stück schlauer

#14

Mag komisch klingen, aber das ‘unstrukturiert’ aufzuschreiben, hat mir bei der ‘Musterlösung’ geholfen. :slight_smile:

#15

Somit ist also das Thema fertig/closed?

#16

Könnte man so sagen, ja. Es sei denn, mir fällt noch eine (andere) Frage ein. Das Proggi darf, wie gesagt, (verständlicherweise) nicht gepostet werden. :S

#17

Dann könnte das Thema ein Mod oder der TO schließen, wenn es geschlossen werden kann, da alle Klarheiten beseitigt wurden

#18

kein Thread wird einfach so geschlossen, niemand braucht Moderator-Hinweise zu geben, einfach nur schweigen, dann ist das Ziel erreicht…
die letzten 5 Postings mit unsinnigen Austausch dazu könnten allerdings gelöscht werden, dieser Gast mit immergleicher IP fällt (mir zumindest) immer negativer auf…

ich setze noch auf Gelöst, weil CyborgBeta auch mit fast 100 Themen dazu anscheinend nicht in der Lage ist obwohl zugestimmt?

#19

unsinniger Austausch?, hoffentlich nicht hier!

Danke

(und Unregistered, könnte sich auch registrieren, wenn er denn möchte)