# Zugriffsverletzung beim Schreiben an Adresse .. Wo ist der fehler?



## schuetzejanett (12. Dezember 2008)

Hallo ich habe beim Ausführen eine Zugriffsverletzung beim Schreiben auf eine bestimmte Adresse. Allerdings finde ich den Fehler nicht.

Könnt ihr mir vielleicht sagen wo der fehler liegt.

Also ich habe eine abstrakte klasse Function mit einer Variable area vom Typ Area. In der Kindklasse Sphere möchte ich dieses Feld setzen und dabei kommt es dann zu der Zugriffsverletzung beim Schreiben.

Hoffe es ist ausreichend wenn ich die beiden Klassen hier poste, und nicht den rest drum herum mit, wenn es nicht ausreicht poste ich den rest gerne noch.
Function.h

```
#pragma once
using namespace std;

class Function abstract
{
protected:
	float u0, u1, v0, v1;
	Area *m_area;
public:
	
	 Function(void) ;
	 Area *getArea();
	
	virtual CPunkt3D calcFacePoint(float, float) = 0;
	virtual ~Function(void) ;
};
```

Function.cpp

```
#include "StdAfx.h"
#include "Function.h"

Function::Function(void) 
{	
}

Function::~Function(void)
{
}

Area* Function::getArea()
{
	
	*m_area = Area(u0,u1,v0,v1);		
	return m_area;
}
```

Sphere.h

```
#pragma once

class Sphere  :
	public Function
{

private:
	float radius;

public:
	Sphere(float,float,float,float,float);
	~Sphere(void);

	CPunkt3D calcFacePoint(float, float );
};
```

Sphere.cpp

```
#include "StdAfx.h"
#include "Sphere.h"

Sphere::Sphere(float ra,float in_u0=(-M_PI/2) ,float in_u1=(M_PI/2), float in_v0=0,float in_v1=2*M_PI)
{
	radius = ra;
	u0 = in_u0;
	u1 = in_u1;
	v0 = in_v0;
	v1 = in_v1;
	
	*m_area = Area(u0,u1,v0,v1);//hier kommt die zugriffsverletzung

}

Sphere::~Sphere(void)
{

}

CPunkt3D Sphere::calcFacePoint(float u, float v)
{
	float x,y,z;
	
	//Berechnung des Punktes und Umrechnung in Bogenmass
	x = (radius * cos(u)*cos(v))/180*M_PI;
	y = (radius * cos(u)*sin(v))/180*M_PI;
	z = (radius * sin(u))/180*M_PI;	
	return (CPunkt3D (x,y,z));
}
```


----------



## vfl_freak (12. Dezember 2008)

Moin,

sehr hilfreich wäre die konkrete Fehlermeldung sowie die Stelle in den Sourcen, wo sie auftritt ! ! !

BTW: was ist "area" ? ? ?

Gruß
Klaus


----------



## schuetzejanett (12. Dezember 2008)

Hallo,

Der Fehler tritt im konstruktor von Sphere auf, beim Anlegen von Area auf. 
Hier ist die genaue Fehlermeldung.

Eine Ausnahme (erste Chance) bei 0x00419f8e in Template_Prak2.exe: 0xC0000005: Zugriffsverletzung beim Schreiben an Position 0xcccccccc.
Unbehandelte Ausnahme bei 0x00419f8e in Template_Prak2.exe: 0xC0000005: Zugriffsverletzung beim Schreiben an Position 0xcccccccc.

Die Klasse Area ist eine Klasse die ein Rechteck aufspannt.

Area.h

```
#pragma once

class Area
{
public:
	float u0, u1, v0, v1;

	Area();
	Area(float, float, float, float);
	~Area(void);
};
```

Area.cpp

```
#include "StdAfx.h"
#include "Area.h"

Area::Area(float in_u0, float in_u1, float in_v0, float in_v1)
{
	u0 = in_u0;
	u1 = in_u1;
	v0 = in_v0;
	v1 = in_v1;
}

Area::Area()
{
	u0 = 0.0;
	u1 = 0.0;
	v0 = 0.0;
	v1 = 0.0;
}
Area::~Area(void)
{
}
```


----------



## deepthroat (12. Dezember 2008)

Hi.

Erstmal ist es gar keine gute Idee "using namespace" in Headerdateien zu verwenden, das verseucht den globalen Namensraum für alle danach eingebundenen Dateien.

Warum verwendest du einen Zeiger für m_area bzw. warum versuchst du in der getArea Methode m_area zu ändern? Die getArea Methode sollte *const* sein!

Wenn, dann gehört die Instanziierung von m_area in den Konstruktor oder in eine setArea Methode.

Der Fehler tritt auf, da du m_area keinen Speicher zugewiesen hast. Du dereferenzierst einen ungültigen Zeiger!

```
Function::Function() : m_area(new Area(u0,u1,v0,v1)) {
}

Function::~Function() {
  delete m_area;
}

Area* getArea() const {
  return m_area;
}
```
Gruß

PS: Wenn deine Objekte immer eine Area haben, dann solltest du keinen Zeiger einsetzen. Ich nehme an, du hast dann auch den Kopierkonstruktor und Zuweisungsoperator für deine Klasse überschrieben?


----------



## schuetzejanett (12. Dezember 2008)

Hallo danke deine hilfe war genau richtig,

das using namespace ist drin, weil ich in der Klasse mal einen Vector gebraucht habe, dn habe ich aber ausgelagert. Und ohne das using namespace hatte ich bei Verwendung von vector immer Fehler.

Das mit dem const bei getArea habe ich geändert. Aber warum ist es falsch für m_Area einen Zeiger zu verwenden, dachte man sollte so oft wie möglich zeiger verwenden.

Programmiere eigentlich eher Java, deswegen die vielleicht dumme Frage.


----------



## deepthroat (12. Dezember 2008)

schuetzejanett hat gesagt.:


> Hallo danke deine hilfe war genau richtig,
> 
> das using namespace ist drin, weil ich in der Klasse mal einen Vector gebraucht habe, dn habe ich aber ausgelagert. Und ohne das using namespace hatte ich bei Verwendung von vector immer Fehler.


Ja, das ist normal, da vector im Namensraum std deklariert ist. Da muß man dann in der Headerdatei den Namensraum explizit spezifizieren: 
	
	
	



```
std::vector
```



schuetzejanett hat gesagt.:


> Das mit dem const bei getArea habe ich geändert. Aber warum ist es falsch für m_Area einen Zeiger zu verwenden, dachte man sollte so oft wie möglich zeiger verwenden.


Falsch habe ich nicht gesagt. Aber gibt es einen Grund dafür? Zeiger müssen verwaltet werden und häufiges new/delete führt zu Einbußen der Geschwindigkeit.

Es macht anscheinend für deine Objekte keinen Sinn wenn m_Area 0 ist, da du davon ausgehst, das m_Area immer auf ein gültiges Objekt zeigt. Dann kannst du aber gleich eine "normale" Variable verwenden, die dann automatisch angelegt und wieder mit dem Objekt aufgeräumt wird. In der getArea Methode könntest du z.B. eine konstante Referenz darauf zurückgeben.

Wenn du allerdings auf Polymorphie von Objekten angewiesen bist, dann müßtest du Referenzen oder Zeiger verwenden.

Gruß


----------

