C++ Structs und Pointer

F

Furtano

Gast
Hallo,

mein C++ Programm stürzt bei sowas ab.
Weshalb ?

Danke =)

Code:
struct Stats {
	int eggs;
	int grubs;
	int puppets;
	int imagos;
	int livingAnts;
	int days;
	int months;
	int years;
	int stats_number_of_living_ants;
	int avgSpeed;
};
Stats *stats;

int main(int argc, char** argv)
{

stats->avgSpeed = 0;

return 0;
}
 
Weil die Variable stats ein Zeiger auf eine Struktur/Klasse Stats ist. Der Zeiger ist aber nicht initialisiert, d.h. er zeigt nirgendwo hin. Du kannst ihn so initialisieren:
stats = new Stats;
 
Am besten vermeidet man den Pointer und definiert die Instanz direkt
Code:
Stats stats;
// Zugriff mittels .-Notation
stats.avgSpeed = 0;
 
Wenn du den Umgang mit Pointern aber explizit lernen willst:

Code:
Stats *stats;
...
stats = new Stats();
stats->avgSpeed = 0;
...
delete stats;

Wichtig ist, dass du mit new Speicher für ein Struct vom Typ Stats reservierst und diesem mit delete wieder freigibst, sobald du ihn nicht mehr benötigst. Nach delete darfst du nicht mehr auf die Adresse in dem Pointer zugreifen, da dieser Bereich schon freigegeben wurde.
 
Zuletzt bearbeitet:
@convexus
Wenn ich stats dann aber per Methode übergeben will, ist das doch ein Nachteil, weil dann der ganze Struct kopiert wird, und nicht der Zeiger, oder?
 
Übergabe ohne Kopieren geht wie Matyro bereits geschrieben hat per Referenz

Code:
// nicht änderbarer Parameter, wenn man Seiteneffekte exlizit auschließen will
int avgSpeed(const Stats& stats) {
  return stats.avgSpeed;
}

// änderbarer Parameter
int avgSpeed(Stats& stats) {
  return stats.avgSpeed;
}
 
Egal wie du die struct anlegst, also als automatische (Stack-) Variable, als HeapVariable oder als globale statische Variable, du kannst sie immer per Pointer, per Value oder per Referenz übergeben.

z.B.

Code:
void ByValue(float Value);
void ByRef(float& Ref);
void ByPointer(float* Pointer);

...

float* Pointer = new float;
float StackVar;

ByValue(*Pointer );
ByRef(*Pointer);
ByPointer(Pointer);

ByValue(StackVar );
ByRef(StackVar);
ByPointer(&StackVar);

Die einizge Ausnahme dazu stellen automatische Registervariablen dar, welche mit dem Register Keyword deklariert worden sind z.B.
Code:
register float FloatInRegister;
Die Ursache hierfür ist, dass Register keine Speicheraddresse besitzen, weshalb man nicht den & Operator auf sie anwenden kann. Da das Register-Schlüsselwort aber eh deprecated ist und von moderenen Compilern ignoriert wird, kann es dir egal sein.


@convexus
Wenn ich stats dann aber per Methode übergeben will, ist das doch ein Nachteil, weil dann der ganze Struct kopiert wird, und nicht der Zeiger, oder?

Ich würde mir darum keine Sorgen machen, dass das im Speziellen die Performance reduziert, da der Compiler selbst ganz gut das Übergeben an Funktionen optimieren kann. In der Regel sind deine Funktionen gar keine Funktionsaufrufe mehr sondern sowieso komplett geinlint.
 
Zuletzt bearbeitet:
Zurück
Oben