![]() |
![]() |
|
![]() |
![]() |
|
Programmierung Rat & Tat für Programmierer |
![]() |
|
Themen-Optionen | Ansicht |
![]() |
#11 |
Inventar
![]() Registriert seit: 24.01.2001
Beiträge: 5.631
|
![]() @fabsi: Bitteschön
![]() Das reicht aus ! Der initStruktur(pStruktur) Aufruf ist ja ein Versorgen der Datenfelder dieser Struktur. Insofern genau das was ich angesprochen habe mit dem Versorgen vor dem Aufruf von Arbeitsfunktionen, die diese Struktur benützen. Mir geht es aber um Arbeitsfunktionen, die die Struktur in erster Linie nicht mit Werten beschicken, sondern die Werte diverser Datenfelder der Struktur nach der Übergabe zur Steuerung und als Parameter verwenden. Zu diesem Zeitpunkt ist eine Initialisierung der Struktur per definitionem - zumindest teilweise und im Wesentlichen - erfolgt - Ergänzungen, Übersteuerungen und Standardwertversorgungen einmal ausgenommen. |
![]() |
![]() |
![]() |
#12 |
Veteran
![]() |
![]() @kikakater
aso, ok. Im allgemeinen denkt man auch an Arbeitsfunktionen und für die muß das natürlich zutreffen. |
![]() |
![]() |
![]() |
#13 | |
Veteran
![]() |
![]() Zitat:
Gibts eine Möglichkeit nur Pointer zu übergeben und trotzdem sicherzustellen, dass die Funktion die Daten auf die der Pointer zeigt nicht verändert? |
|
![]() |
![]() |
![]() |
#14 |
Inventar
![]() Registriert seit: 24.01.2001
Beiträge: 5.631
|
![]() Die Möglichkeit gibt es: Einfach in der Funktion nicht auf die Datenfelder schreibend zugreifen.
Eine andere Variante gibt es nicht, sollte eigentlich logisch sein ... Nur in C++ gibt es einen protected Zusatz, der bezieht sich aber wiederum nur auf Funktionen, die nicht auf protected Variablen zugreifen dürfen. Mit anderen Worten schaut die Sache letztgültig so aus ( ![]() 1. Struktur allozieren 2. Strukturfelder initialisieren 3. Struktur in Arbeitsbereich (Strukturkopie) kopieren 4. Funktionsaufruf mit den bösen Veränderungen machen mittels Übergabe eines Adresszeigers auf die Strukturkopie 5. Glücklich sein, daß die Originalstruktur so bestehen bleibt wie sie vor dem Aufruf der Funktion ausgesehen hat, sprich die Weiterverwendung der ursprünglichen Werte geht durch das Kopieren und Verwenden der Kopie anstatt des Originals in Ordnung mfg Kikakater |
![]() |
![]() |
![]() |
#15 | ||||
Veteran
![]() |
![]() Zitat:
![]() Selbiges würde aber auch für alle anderen Variablen gelten, also warum gibts dann aberhaupt const? Zitat:
Zitat:
Zitat:
2 Strukturen mit den selben Werten, eine zum Arbeiten und eine als Backup erscheint mir nicht zweckmässig. Ein Beispiel: ich hab die Oberstruktur main. Diese enthält ALLE globalen Daten, alles was irgendwie von mehr als einer Funktion des ganzen Programms benutzt werden muß, wie zum Beispiel main.config.{ganzvieleconfigdaten} als auch main.workload.{1000 int variablen die modifiziert werden}. Die funktion funktion(&main.workload,&main.config) modifiziert jetzt die Werte der 1000 int variablen in main.workload. Auf main.config{*.*} wird nur lesend zugegriffen (das kann ich ja selbst bestimmen). Dann wäre es aber schön, wenn man die Configurationsstruktur auch nur lesbar übergeben kann. (wie beim öffnen einer Datei, da kann ich ja auch aussuchen, ob r_only, rw, usw). Mit 2 Strukturen könnte ich anschliessend mainkopie.config nach main.config kopieren. So bleibt meine Konfiguration zwar sicher erhalten, da ja alle Modifikation in main.config überschrieben werden (wohlgemerkt, ich würde main.config nicht bewußt in der Funktion modfizieren. Prinzipiell ist es aber ein Sicherheitsrisiko wenn Konfigurationen von überall modifiziert werden können), aber das ganze wird ziemlich unübersichtlich. (@kikakater: allerdings hatte ich die Idee erst durch das Lesen deines Postings). Und speichersparend ist das auch nicht. |
||||
![]() |
![]() |
![]() |
#16 |
Inventar
![]() Registriert seit: 24.01.2001
Beiträge: 5.631
|
![]() Wenn schon kopierst du main.config auf mainkopie.config oder ?
Man kopiert doch in Richtung Kopie und nicht umgekehrt ? Der Smilie und *seufz* als Bemerkung geht Richtung C, und nicht an Dich für Dein Nachfragen ![]() Du kannst Sie ja lesend übergeben nur stehen dann 2000 Bytes am Stack und müssen von dort wieder entfernt werden (Call by Value mit Zusatz const bezogen auf "Datenfeld" - in diesem Fall Struktur - ."config" (zu Struktur "main" zugehörig). Nach dem Aufruf der Funktion die Kopie auf das Original zu kopieren und zu behaupten, daß die Originalwerte erhalten bleiben ist Veräppelung aber sonst schon gar nichts. Im Übrigen wird die Technik des Versorgens eines Arbeitsbereichs aus einem Originalbereich in der Praxis bei Softwarefirmen sehr wohl verwendet und ist oftmals notwendig um Seiteneffekte (eben das unabsichtliche Überschreiben von Datenfeldern) im Originalbereich, der innerhalb des RAM Speichers gelegen ist, von vornherein auszuschliessen. Dies ist Profialltag, also was solls. Gehirn anstrengen - gut und schön - es gibt aber keinen Schutz vor gewollter Veränderung der Werte, das ist ein Widerspruch in sich. Wenn Du einen Einkauf machst musst Du alle Posten zusammenzählen. Ebenso verhält es sich beim Programmieren (schützenswerte Originalstruktur oder -record im Fall von Pascal etc. und veränderbrae temporäre Strukturkopie). Das ist Programmieren, der Kunst Zügel anzulegen ist das Argument hier nicht. Es handelt sich um "künsteln" und außerdem sollte die Kunst des Programmierens auf das Einhalten von Programmiernormen sich einschränken = täglich gelebter Alltag. Eine Originalstruktur, die verändert werden darf oder muss, braucht selbstnafreilich keine Kopie um an Ihre sie zu verändernde Funktion übergeben zu werden. |
![]() |
![]() |
![]() |
#17 | ||||||
Veteran
![]() |
![]() Zitat:
Zitat:
Zitat:
![]() Zitat:
Zitat:
Zitat:
Auf die Gefahr hin, das ich nerve weil ich mich wiederhole: main.config -> wird am Anfang inititalisiert, und nachher NUR mehr gelesen. main.workload ist das zu bearbeitende Unterelement. Kopie mach ich natürlich von der ganzen main Struktur. Und da ist main.workload auch dabei. (oder?? Vielleicht macht es mehr Sinn Unterelemente wie .config zu Kopieren, und die Kopie zu übergeben. Das erfordert aber, bei realistischeren Strukturen als meine main, viel Disziplin um einen überscihtlichen Code zu erzeugen) Hey, aber Danke für die Anregungen, hilft mir sehr! |
||||||
![]() |
![]() |
![]() |
#18 |
Inventar
![]() Registriert seit: 24.01.2001
Beiträge: 5.631
|
![]() Schutz vor Überschreiben geht bei der Programmausführung nur durch das Anlegen und Versorgen einer Kopie.
Du postest weder die Struktur(en) selbst (struct .... { } ; ) noch hältst Du Dich sonst irgendwie mit Klarheiten auf. Schreib doch einfach: 1) main.config -> mainkopie.config bzw. kopieconfig (letzteres vermute ich eher) 2) Funktionsaufruf mit (&kopieconfig) 3) Glücklich, daß main.config erhalten geblieben ist Variante A: Du solltest bei so grossen (vermute ich) Strukturen, den ganzen Bereich als Übergabebereich wählen und config und workload fix als Variablenfelder (=Strukturvariablenfelder) einplanen. Nämlich insofern, daß der Bereich (also die Struktur) "main" als & (address of) "main" übergeben wird und config und workload entsprechend ihrer auszulesenden und zu verändernden Bedeutung bekannt sind. Zu verändernde Strukturen wie workload kopierst Du dann INNERHALB der Funktion in dynamisch angeforderten Speicher. Variante B: Das beste ist und bleibt aber folgendes: Schreibe eine Wrapper(=Hüll)funktion, die .workload in local_workload kopiert und local_workload sowie main als Adresszeiger auf ihre Bereiche annimmt. Also: Funktion Wrapperfunktion(struct xy_config *pconfig, struct xy_workload *pworkload): 1) struct xy_workload local_workload; // steht am Stack, deswegen besser als dynamischer Speicher, Stichwort Garbage Collection immer wieder notwendig wegen Speicherlücken 2) kopieren *pworkload in local_workload 3) Aufruf: Arbeitsfunktion(pconfig,&local_workload); 4) *pworkload (falls so verwendet ist das main.workload) bleibt erhalten, local_workload ist vielleicht verändert, je nachdem was in der Funktion Arbeitsfunktion passiert. Dein Aufruf lautet also dann: Wrapperfunktion(&main.config,&main.workload); Sollte das beste sein, was nicht nur C, sondern ein Algorithmus überhaupt "hergeben" kann. In Zukunft rufst Du nurmehr Wrapperfunktion(...) auf anstatt Arbeitsfunktion. Und zwar deswegen, weil workload erhalten bleiben soll. Soll config erhalten bleiben und es besteht die Gefahr, daß die Funktion Arbeitsfunktion(...) diesen Parameterblock verändert, muss halt eine Kopie von config gemacht werden und diese lokale Kopie per Adresszeiger an die Funktion übergeben werden. mfg Kikakater |
![]() |
![]() |
![]() |
#19 |
Veteran
![]() |
![]() Danke für den Input.
Ich hab absichlich jeglichen Code vermieden. Ich glaube sprachlich läßt sichs universeller umsetzen. Ausserdem handelt es sich dabei um ein gedankliches Konstrukt ich hab hier nichts vor mir liegen, das main, main.config oder sonst irgendwas ist. main.workload ist nicht relevant. Die Daten werden bearbeitet und sollen bearbeitet werden, anhand von Information aus main.config, welches die Daten enthält, die konfigurieren, wie main.workload bearbeitet wird. D.h. main.workload zu kopieren ist uninteressant, main.config ist das schützenswerte. Aber das so auf deine Wrapperfunktion umzumünzen sollte so schwer nicht sein. Ziel der Funktion ist es ja nur, Konstanten (wie bestimmte Strukturteile usw.), die nicht von Arbeitsfunktion verändert werden soll (egal ob sies jetzt theorethisch könnten oder nicht), zu kopieren, und den Pointer auf die Kopie zu übergeben, was ca dem entspricht was mir eh schon vergeschwebt ist. Das alles allerdings auch noch übersichtlich zu halten wird schwer, vielleicht fällt mir noch was anderes ein. thx |
![]() |
![]() |
![]() |
#20 |
Inventar
![]() Registriert seit: 24.01.2001
Beiträge: 5.631
|
![]() Bitte
![]() Viel Erfolg weiterhin ... |
![]() |
![]() |
![]() |
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1) | |
|
|