Seite 1 von 2

allgemeine Frage zu Pointern

Verfasst: 10.03.2014 16:28
von SBond
ähhh...

ich traue mich fast nicht meine folgende dumme Frage zu stellen. ...ich hoffe einfach mal, dass ihr mich nicht schlachten werdet...
Wann ist der Einsatz von Pointern sinnvoll? Wenn ich programmiere, dann verwende ich in 3000 Programmzeilen eventuell mal einen Pointer. Meistens nur dann, wenn ich irgendetwas im Speicher machen muss.

Prinzipiell schaue ich mir gerne fremde Programmierarbeiten an, um so ggf. meine Programmstrukturen zu verbessern. Wenn ich mir die geposteten Quellcodes von unseren Mods/Admins/Power-Usern anschaue, dann fällt mir immer wieder die große Anzahl der verwendeten Pointern auf. Ich denke mal Pointer bieten je nach Aufgabenbereich einen Geschwindigkeitsvorteil, aber bieten diese noch weitere Vorteile?


viele Grüße,
SBond

Re: allgemeine Frage zu Pointern

Verfasst: 10.03.2014 16:56
von NicTheQuick
Aus meiner Erfahrung kann ich da folgendes sagen:

- Pointer sind nützlich, wenn man direkt mit Speicher arbeitet, der in der Regel mit 'AllocateMemory()' erstellt wurde.
- Oder bei Stringmanipulationen können sie auch wesentlich effizienter eingesetzt werden als Alternative zu 'Mid()', 'Asc()', 'Chr()' und Konsorten.
- Oder wenn man mit externen Bibliotheken arbeitet wie bspw. der WinAPI. Da gibt es viele Befehle, bei denen man direkt mit Speicherebereichen arbeitet.
- Manche Leute nutzen Pointer auch als Alternative zu Integer, wenn sie zum Beispiel ein Handle speichern wollen. Hinter einem Handle steht meistens auch nur ein allozierter Speicherbereich.


Für Anfänger sind Pointer aus folgenden Gründen mit Vorsicht zu genießen:

- Man kann schnell ungültige Pointer erzeugen, wodurch das Programm abstürzt.
- Man kann auch gültige, aber falsche Pointer erzeugen, die in Speicherbereiche schreiben, in die sie lieber nicht hätten schreiben sollen.
- Wenn man mit 'AllocateMemory()' Speicher alloziert, dann muss man ihn auch wieder freigeben, wenn man ihn nicht mehr benutzt. Ansonsten gibt es ein Speicherleck.
- Ob Pointer auf Pointer oder doch nur ein normaler Pointer, ist vielleicht nicht jedem gleich klar.
- Nebeneffekte können schön auftreten, weil man einer Procedure zum Beispiel einen Pointer zu einem String übergibt und dieser String dann innerhalb der Procedure geändert wird. Der aufrufende Programmteil merkt das vielleicht nicht und denkt der ursprüngliche String ist immer noch der selbe und versucht damit weiter zu arbeiten, was zu Fehlern führen kann.
- Gerade bei der Verwendung von Pointern zur Stringmanipulation sehe ich immer wieder sehr viele Fehler. Es wird bei der Allozierung vergessen das Nullbyte mit einzuberechnen, Unicode wird nicht berücksichtigt, oder 'Space()' wird einfach als Alternative zu 'AllocateMemory()' genutzt um anschließend binäre Daten darin zu verwalten.
- Probleme durch Pointer können schnell auch dazu führen, dass das Programm an einer ganz anderen Stelle abstürzt als an der Stelle, wo der Fehler gemacht wurde.

Generell gilt bei Pointer: Wenn man sich unsicher ist, immer erst mal fragen, ob das so machbar ist, was man vorhat, oder ob man vielleicht schon einen ganz falschen Ansatz genommen hat. Außerdem gilt: Purifier einschalten.

Re: allgemeine Frage zu Pointern

Verfasst: 10.03.2014 17:41
von STARGÅTE
Mein Hauptgrund für die Nutzung von Pointer ist die "Notwendigkeit"/Vorteil beim Übergeben einer strukturierten Variable an eine Prozedur:

Code: Alles auswählen

Structure Beispiel
  String.s
  Integer.i
  Float.f
EndStructure

Procedure Beispiel(*Variable.Beispiel)
  Debug *Variable\String
  Debug *Variable\Float
  *Variable\Integer + 1000
EndProcedure

Define Test.Beispiel
Test\String = "Hallo Welt!"
Test\Float = 3.141592
Test\Integer = 1024

Beispiel(Test)

Debug Test\Integer
In diesem Code definiere ich mit eine Struktur und eine Variable mit dieser Struktur (Define Test.Beispiel)
Danach übergebe ich die Variable an die Prozedur. In PureBasic werden alle strukturierten Variablen immer als Pointer übergeben, dass hießt, die Prozedur bekommt nur die Adresse wo der Inhalt der Variable im Speicher liegt.
In der Prozedur definiere ich also ein Pointer mit der gleichen Struktur und kann somit bequem auf den Inhalt zugreifen und ihn sogar verändern.

Re: allgemeine Frage zu Pointern

Verfasst: 10.03.2014 18:07
von SBond
vielen Dank für die Tipps :D

bei dir STARGÅTE sieht man das recht häufig. Ich nutze mittlerweile auch sehr viele Struktuken, aber ich übergebe diese nie an Prozeduren. Da beantworten sich viele Fragen schon fast von selbst. Ich halte bei mir Strukturen in der Regel immer global und fächer diese in eine Baumstruktur. Zumindest bis jetzt habe ich noch keine Nachteile darin gesehen und desshalb waren auch noch nie Pointer notwendig. :mrgreen:

Re: allgemeine Frage zu Pointern

Verfasst: 10.03.2014 22:21
von Chimorin
Global ist schön und gut, kann aber zu Fehlern führen (Hat man mir berichtet).

Wenn dein Code erst einmal eine gewisse Größe erreicht hat, möchte man seine Prozeduren in andere .pb Dateien auslagern. Dies können aber meines Wissensstandes nach nicht mit globalen Variablen des Hauptprogrammes umgehen.

Re: allgemeine Frage zu Pointern

Verfasst: 10.03.2014 22:42
von SBond
Chimorin hat geschrieben:Global ist schön und gut, kann aber zu Fehlern führen (Hat man mir berichtet).
hmm... ok, das ist mir neu. Zumindest gab es bisher keine Probleme. Kann das jemand bestätigen?
Mit der Sache zum Thema Auslagern hast du natürlich recht. Das kann ggf. problematisch sein. Allerdings habe ich meine aktuellen Projekte die größer 15K Programmzeilen werden in Module zerlegt. Das bietet zudem den großen Vorteil, dass ich die Strukturen Kapseln und vor "fremden" Prozeduren Schützen kann.

Interessant wäre dann ja die Frage, wie sollte eine große Anzahl Variablen am besten verwaltet werden? Ich besitze in der Regel nur eine große baumförmige Struktur (ggf. pro Modul). Variablen können somit immer eindeutig identifiziert werden. Außerdem achte ich sehr darauf, dass ich in Prozeduren jede verwendete (temporäre) Variable mit "Protected" deklariere.

Dies können aber meines Wissensstandes nach nicht mit globalen Variablen des Hauptprogrammes umgehen.
....die Auslagerung der Prozeduren in .pb-Dateien ist prinzipiell unkrittisch, sofern diese nicht in andere Projekte portiert werden sollen. ;)
Das habe ich vor der Einführung der Module in PBv5.20 in vielen Projekten gemacht.

Re: allgemeine Frage zu Pointern

Verfasst: 10.03.2014 22:51
von ts-soft
Chimorin hat geschrieben:Global ist schön und gut, kann aber zu Fehlern führen (Hat man mir berichtet).

Wenn dein Code erst einmal eine gewisse Größe erreicht hat, möchte man seine Prozeduren in andere .pb Dateien auslagern. Dies können aber meines Wissensstandes nach nicht mit globalen Variablen des Hauptprogrammes umgehen.
Es kommt immer drauf an, wo die globale Variable deklariert wurde, weil erst ab diesem Teil ist sie bekannt. Solange man EnableExplicit
nutzt, bekommt man dies aber mit.

Beispiel:

Code: Alles auswählen

;EnableExplicit

Procedure Foo1()
  Debug test
EndProcedure

Global test = 25

Procedure Foo2()
  Debug test
EndProcedure

Foo1()
Foo2()
Also immer alles was überall Global gültig sein soll, ganz an den Anfang des Codes deklarieren!

Bei vielen globalen Variablen, vor allem in längeren Codes, kommt man schnell durcheinander,
es ist wirklich besser, globale Variablen zu vermeiden, wenn möglich.

Gruß
Thomas

Re: allgemeine Frage zu Pointern

Verfasst: 10.03.2014 22:59
von NicTheQuick
Angelehnt an ts-softs Beispiel noch eine Variante mit Shared. Shared kann man eigentlich gut an Stelle von Global nutzen:

Code: Alles auswählen

;EnableExplicit
;Define test.i

Procedure Foo1()
	Shared test
	Debug test
EndProcedure

test = 25

Procedure Foo2()
	Shared test
	Debug test
EndProcedure

Foo1()
Foo2() 
Mit 'EnableExplicit' muss man aber natürlich dennoch ein 'Define' voran schreiben.

Re: allgemeine Frage zu Pointern

Verfasst: 10.03.2014 23:08
von SBond
Shared habe ich zumindest bisher noch nie wirklich genutzt :)

Re: allgemeine Frage zu Pointern

Verfasst: 20.03.2014 22:54
von _sivizius
Im Prinzip stehen die Gründe für Pointern alle in der Hilfe.
  • Strukturen, Interfaces, Prototypen
  • Strings, Arrays, Lists etc sind letztlich auch Pointer
  • genannte Speicheroperationen, schnellere Stringbefehle etc
  • gerne genutzt als Rückgabewert von Proceduren, um mehrere Ergebnisse einfach zu übergeben
  • ein wenig objektorientierte Programmierung ist ganz toll, Objekte sind Pointer, siehe Interfaces/Strukturen/Prototypen
ich komme mittlerweile gar nicht mehr ohne mindestens einen Pointer im Code aus :P.
zu den Problemen mit Pointern:
  • erfinde nie einen Wert für einen Pointer, nutze AllocateMemory(), @variable, @procedure(), ?label
  • Prüfe (ständig) auf echte Pointer. Null-Pointer und falsche Pointer führen zu Fehlern.
  • Bleibe im Bereich. Wenn du über einen Pointer iterierst, checke ob die Länge eingehalten wurde und schreibe nicht mehr, als du Platz hast
  • Räume auf.