allgemeine Frage zu Pointern

Anfängerfragen zum Programmieren mit PureBasic.
SBond
Beiträge: 266
Registriert: 22.05.2013 20:35

allgemeine Frage zu Pointern

Beitrag 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
41 6c 73 6f 20 77 65 6e 6e 20 64 75 20 73 6f 20 76 69 65 6c 20 4c 61 6e 67 65 77 65 69 6c 65 20 68 61 73 74 2c 20 64 61 6e 6e 20 6b 61 6e 6e 73 74 20 64 75 20 61 75 63 68 20 67 6c 65 69 63 68 20 7a 75 20 6d 69 72 20 6b 6f 6d 6d 65 6e 20 75 6e 64 20 61 62 77 61 73 63 68 65 6e 2e

:D
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: allgemeine Frage zu Pointern

Beitrag 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.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: allgemeine Frage zu Pointern

Beitrag 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.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
SBond
Beiträge: 266
Registriert: 22.05.2013 20:35

Re: allgemeine Frage zu Pointern

Beitrag 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:
41 6c 73 6f 20 77 65 6e 6e 20 64 75 20 73 6f 20 76 69 65 6c 20 4c 61 6e 67 65 77 65 69 6c 65 20 68 61 73 74 2c 20 64 61 6e 6e 20 6b 61 6e 6e 73 74 20 64 75 20 61 75 63 68 20 67 6c 65 69 63 68 20 7a 75 20 6d 69 72 20 6b 6f 6d 6d 65 6e 20 75 6e 64 20 61 62 77 61 73 63 68 65 6e 2e

:D
Benutzeravatar
Chimorin
Beiträge: 451
Registriert: 30.01.2013 16:11
Computerausstattung: MSI GTX 660 OC mit TwinFrozr III
6Gb DDR 3 RAM
AMD Phenom II X4 B55 @ 3,6GHz
Windows 7 Home Premium 64-bit

Re: allgemeine Frage zu Pointern

Beitrag 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.
Bild

- formerly known as Bananenfreak -
SBond
Beiträge: 266
Registriert: 22.05.2013 20:35

Re: allgemeine Frage zu Pointern

Beitrag 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.
41 6c 73 6f 20 77 65 6e 6e 20 64 75 20 73 6f 20 76 69 65 6c 20 4c 61 6e 67 65 77 65 69 6c 65 20 68 61 73 74 2c 20 64 61 6e 6e 20 6b 61 6e 6e 73 74 20 64 75 20 61 75 63 68 20 67 6c 65 69 63 68 20 7a 75 20 6d 69 72 20 6b 6f 6d 6d 65 6e 20 75 6e 64 20 61 62 77 61 73 63 68 65 6e 2e

:D
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: allgemeine Frage zu Pointern

Beitrag 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
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: allgemeine Frage zu Pointern

Beitrag 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.
SBond
Beiträge: 266
Registriert: 22.05.2013 20:35

Re: allgemeine Frage zu Pointern

Beitrag von SBond »

Shared habe ich zumindest bisher noch nie wirklich genutzt :)
41 6c 73 6f 20 77 65 6e 6e 20 64 75 20 73 6f 20 76 69 65 6c 20 4c 61 6e 67 65 77 65 69 6c 65 20 68 61 73 74 2c 20 64 61 6e 6e 20 6b 61 6e 6e 73 74 20 64 75 20 61 75 63 68 20 67 6c 65 69 63 68 20 7a 75 20 6d 69 72 20 6b 6f 6d 6d 65 6e 20 75 6e 64 20 61 62 77 61 73 63 68 65 6e 2e

:D
Benutzeravatar
_sivizius
Beiträge: 98
Registriert: 23.10.2013 15:21

Re: allgemeine Frage zu Pointern

Beitrag 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.
Antworten