Speichalloziirung in Kon-Destruktoffunktionen

=> Der Destruktor wird aufgerufen(in deinem Fall) und das im Konstruktor allzoiierte Objekt (i)
wird wieder freigegeben. Nach verlassen des Destruktors wird der Speicherplatz des
Objektes test auch wieder freigegeben und alles ist perfekt

Wenn du dich um sowas nicht kümmern möchtest lass es dir von C++ automatisch machen
und erzeuge die Objekt auf dem Stack, somit werden die Objekte nach verlassen des
Blocks in dem sie deklariert wurden automatisch wieder destruiert und du ersparst dir
das manuelle Löschen via delete und verhinderst vielleicht die von dir gefürchteten
Speicherlecks....
Perfekt ist das eigentlich nicht. Der Compiler generiert nämlich bei Bedarf einen Copy Constructor, zum Beispiel, wenn ein Objekt als Parameter per Wert übergeben wird. In diesem Fall wird im Destruktor der Kopie versucht, Speicher über einen ungültigen Pointer freizugeben. Das ist ziemlich unangenehm. Dasselbe passiert bei der Zuweisung.
Die einzige Lösung ist es, selbst einen sinnvollen Kopierkonstruktor sowie einen Zuweisungsoperator zu definieren.
 
Kachelator hat gesagt.:
Perfekt ist das eigentlich nicht. Der Compiler generiert nämlich bei Bedarf einen Copy Constructor, zum Beispiel, wenn ein Objekt als Parameter per Wert übergeben wird. In diesem Fall wird im Destruktor der Kopie versucht, Speicher über einen ungültigen Pointer freizugeben. Das ist ziemlich unangenehm. Dasselbe passiert bei der Zuweisung.
Die einzige Lösung ist es, selbst einen sinnvollen Kopierkonstruktor sowie einen Zuweisungsoperator zu definieren.

Das is natürlich nicht zu schlagen :)
Allerdings stimmt das mit dem eingebauten operator= nur teilweise (kommt auf den Compiler
an).
Wenn der eingebaute Zuweisungsoperator mit Wertübergabe- und Rückgabe arbeitet dann
schon weil dann wieder der Copykonstruktor aufgerufen wird. Wenn der Compiler dagegen
optimiert ist und der eingebaute Zuweisungsoperator mit Referenzen implementiert ist,
sollte alles gut gehen und eine Redefinition des operator= is nich nötig.

Im folgenden hab ich noch mal n kleines Beispiel, welches Kachelators These nochmal
demonstrieren sollte:
Code:
#include <iostream>

using namespace std;

class CMyClass {    

        public:
                int* i;
                //Konstruktor
                CMyClass(){
                        cout << "Constructor" << endl;
                        i = new int; //oder eine beliebige andere alloziirung von Speicher
                }

                //eingebauter Cop Konstuktor 
                CMyClass(const CMyClass& c){
                        cout << "Copy constructor" << endl;
                }

                //Destruktor
                ~CMyClass(){
                        cout << "Destructor" << endl;
                        delete i;
                }
        
                //bei Aufruf von foo => aufruf von Copy Konstruktor
                int foo(CMyClass c){
                        cout << "foo" << endl;
                }
                
                //Wenn compiler optimiert ist dann dieser operator=
                //kein aufruf von Copy Konstruktor
                const CMyClass& operator=(const CMyClass& s){                                                                                                                                           
                        cout << "Operator = " << endl;
                        return *this;        
                }
/*
                //andernfalls oder bei Eigendefinition vielleicht dieser operator=
                //aufruf von Copy Konstruktor
                CMyClass operator=(CMyClass s){
                        cout << "Operator = " << endl;
                        return *this;
                }
*/
};

int main(){
        CMyClass c;
        CMyClass s;
        s = c;    //muss nicht unbedingt schief gehen
//      c.foo(s); //geht garantiert schief
        return 0; 
}

Gruß und Kuss

RedWing
 
Zuletzt bearbeitet:
Hallo zusammen,

mit dem Copy Konstruktor ist ja ne feine Sache nur wie kann ich die Sau zwingen ihn aufzurufen

hab ihn hier wie folgt definiert:
Code:
CDevice::CDevice(const CDevice &x) :
		m_dwAddress(x.m_dwAddress),		
		m_bSwVersionKnown(x.m_bSwVersionKnown),
		m_bSpNb(x.m_bSpNb),
		m_bSiNb(x.m_bSiNb),
		m_bBuild(x.m_bBuild),
		m_hr(x.m_hr),
		m_bFailure(x.m_bFailure),
		m_bRemoteControl(x.m_bRemoteControl),
		m_bWriteEnable(x.m_bWriteEnable),
		m_sDeviceAddInfo(x.m_sDeviceAddInfo)
{
	for(std::vector<int>::size_type i(0); i < x.m_Vars.size(); i++)
		m_Vars.push_back(x.m_Vars.at(i));
}

Würde gerne dass er hier aufgerufen wird:

Code:
vector	<CDevice*> apm_AllDevices;
vector	<CDevice*> apm_ConnectedDevices;
//-----------------------------------------------------------------------------
//HIER SOLL DIE SAU AUFGERUFEN WERDEN:
apm_ConnectedDevices[i] = apm_AllDevices[i];

Er wird aber nicht aufgerufen...

Ich initialisiere die Vectoren so:
Code:
const int _KNOWN_DEVICES_CNT = 2;
const BYTE KNOWN_STD_DEVICE_ADDRESSES[_KNOWN_DEVICES_CNT] =
		{BMU_ID, AI_ID};
//-----------------------------------------------------------------------------
	for(int i(0); i < _KNOWN_DEVICES_CNT; i++)
	{

		apm_AllDevices.push_back(new CDevice(KNOWN_STD_DEVICE_ADDRESSES[i]));	
		apm_ConnectedDevices.push_back(NULL);
		apm_UsedDevices.push_back(NULL);
	}

Das Problem ist dass der Copy Konstruktor nicht aufgerufen wird.
Ich dadurch am Ende im D´tor natürlich einen Speicher zugriffsfehler bekomme, da der D´tor
schon die Devices in apm_AllDevices gelöscht hat und dann bei apm_ConnectedDevices
das ganze nochmal probiert...

Grüße
RuFF
 
Zuletzt bearbeitet:
Hi.
RuFFnEcK hat gesagt.:
Das Problem ist dass der Copy Konstruktor nicht aufgerufen wird.
Ich dadurch am Ende im D´tor natürlich einen Speicher zugriffsfehler bekomme, da der D´tor
schon die Devices in apm_AllDevices gelöscht hat und dann bei apm_ConnectedDevices
das ganze nochmal probiert...
Das Problem ist, das du da Pointer kopierst und da wird selbstverständlich kein Kopierkonstruktor aufgerufen. Wenn du willst das da was kopiert wird mußt du das schön selbst erledigen
Code:
apm_ConnectedDevices[i] = new CDevice(*apm_AllDevices[i]);
Dann hast du natürlich 2 Kopien von den CDevice Objekten die du dann auch beide wieder freigeben mußt.

Evlt. solltest du dir mal Smart-Pointer anschauen :google: Damit kannst du Pointer verwalten und kopieren, und der Speicher wird automatisch freigegeben sobald keine Referenz mehr existiert.

In der C++ STL gibt's auch bereits eine Art Smart-Pointer, nämlich auto_ptr. Es ist leider nur keine ganz so gute Idee die Dinger in STL Container zu packen.

Gruß
 
Zuletzt bearbeitet:
Hallöchen,

hups wie ich grad feststellen muss hab ich gaanz vergessen zu bedanken bei dir ;)
Manchmal hab ich einfach n Brett vorm Kopp :D

Letztendlich hab ich mir Gedacht um der OOP gerecht zu werden, darf es die einzelnen Devices nur einmal geben mit all ihren Variablen...und sollte eigentlich verhindern das
Kopien erstellt werden können, aber erstma Wurst muss ja irgendwann mal fertig werden^^

Ich hab da ein weiteres Problem, bei dem es zwar um VBA unter Excel geht, es werden nur zwei der C++ dll Interfaces aufgerufen.
Hab bisher immer nen C++ Client benutzt, den ich immer erweitert hab wenn
ein neues Interface dazu kam... Hab dabei nicht einen Speicherzugriffsfehler oder irgendwelche Speicherlecks...
Aber wenn VBA den Client spielt läuft da gar nix mit den Variablen Klassen.
Hab den Fehler beim Konstruktor Aufruf der Variable KLassen lokalisert, den Fehler jedoch nicht :(
Ich wüsste nicht was der VBA Client anders macht als der C++ Client...
Ob der VBA Client vielleicht empfindlicher ist als der C++ Client?

Das ist jetzt recht viel Code ich schau mal das ich was rauslösche ums übersichtlicher zu machen...

Also der Fehler passiert wenn ich eine Variable erstellen möchte durch den Konstruktor einer expliziten Ableitung wie z.B.
Cvar * m_boolVariable = new CTBool(varName, aType, vaddr, numberOfArrayEntries);
Hab dabei die Übergebenen Werte überprüft und ist alles in Ordnung, selbst die Aufrufreihenfolge der Konstruktoren ist korrekt!

Es kommt zu folgendem Fehler wenn ein Konstruktor zum ersten Mal aufgerufen wird:
Diese Info als modales Fenster:

Unbehandelte Ausnahme bei 0x7c911230 in EXCEL.EXE: Benutzerhaltepunkt.


Und ganz viele hiervon im Debugger (schätze für jede Variable die angelegt wird :D ):

Heap missing last entry in committed range near 2f667c0


Ich hab euch den Code mal stark gekürztz und verschone euch mit allen Methoden, nur das wichtige ;)

//-------------------------------------------------------------------------------------------------------------------
//CVar - Variablenklasse um jede Art von Variablen darstellen zu können
//-------------------------------------------------------------------------------------------------------------------
_MAX_RAWDATA_ARRAY_SIZE = 256
Code:
#pragma once
#include "definitions.h"
#include "Value.h"

class CVar
{
public:
				CVar(void);
				CVar(CString VarName, AddrType AddrTypeOfVar, long AddressOfVar);
virtual			~CVar(void);
//--------------------------------------------------------------------------------
//Datamember
//--------------------------------------------------------------------------------
private:
	CString		m_sName;									//Variablen Name
	AddrType	m_eType;									//Adress Typ (symbolisch, absolut...)
	long		m_dwAddress;								//Adresse der Variable		
public:
	CValue	*	m_Value;									//Used 2 save all interpreted Values, also arrays...
	BYTE		m_abRawData[_MAX_RAWDATA_ARRAY_SIZE];		//Used 2 save all raw data
	BYTE		GetAddr(LowHighAdresses AddressLowHigh);	
//--------------------------------------------------------------------------------
//All get methods:
//--------------------------------------------------------------------------------
	CString		getVarName(void)		{return m_sName;}
//--------------------------------------------------------------------------------
//All std. public methods 4 all DataTypes:
//--------------------------------------------------------------------------------
	void		setVarName(CString Name);				//Changes the var Name
//--------------------------------------------------------------------------------
//All virtual methods that should be implemented by deriving classes...	
//--------------------------------------------------------------------------------
	virtual bool		InterpretRawData(void) PURE;	//Muss von jedem Erber implementiert werden und interpretiert die Rohdaten
};

CVar Implementierung:
Code:
#include "StdAfx.h"
#include ".\var.h"
//------------------------------------------------------------------------------------------------------------------------------------------------------
CVar::CVar(void) :

	m_sName(""),
	m_eType(addrSym),
	m_dwAddress(0x00)
{
	resetRawData();
}
//--------------------------------------------------------------------------------
CVar::~CVar(void)
{
}
//--------------------------------------------------------------------------------
CVar::CVar(CString VarName, AddrType AddrTypeOfVar, long AddressOfVar): 
	
	m_sName(VarName),
	m_eType(AddrTypeOfVar),
	m_dwAddress(AddressOfVar),
	m_Value(NULL)
{
	resetRawData();
}
//------------------------------------------------------------------------------------------------------------------------------------------------------
BYTE CVar::GetAddr(LowHighAdresses AddressLowHigh)
{	//TODO: Was gegen die Compiler Warnung tun! 
	BYTE returnValue;
	if(AddressLowHigh == high)
		returnValue = (m_dwAddress >> 8) & 255;
	else
		returnValue = m_dwAddress & 255;		
	return returnValue;
}
//--------------------------------------------------------------------------------
void CVar::setVarName(CString Name)
{
	//ToDo: Überprüfung der Übergebenen Werte!
	m_sName = Name;
}

//-------------------------------------------------------------------------------------------------------------------
//CInterInfo - Hilfsklasse um Interpretations Informationen (Verknüpfung zwischen Wert und String) zu speichern
//-------------------------------------------------------------------------------------------------------------------
//CValue - Speicherklasse um alle Werte einer Variable zu speichern (Einfache, Arrays, Interpretierte, usw.
//-------------------------------------------------------------------------------------------------------------------

Code:
#pragma once
#include "definitions.h"
//-------------------------------------------------------------------------------------------------------------------
//CInterInfo - Hilfsklasse um Interpretations Informationen (Verknüpfung zwischen Wert und String) zu speichern
//-------------------------------------------------------------------------------------------------------------------
class CInterInfo
{
public:
	CInterInfo(void){;}
	CInterInfo(short nFault, CString sFault) : m_nFault(nFault), m_sFault(sFault){;}
	~CInterInfo(void){;}
	short		m_nFault;
	CString		m_sFault;
};
//-------------------------------------------------------------------------------------------------------------------
//CValue - Speicherklasse um alle Werte einer Variable zu speichern (Einfache, Arrays, Interpretierte, usw.
//-------------------------------------------------------------------------------------------------------------------
class CValue
{
 private:
	//Std. C´tor should not be used -> private!
	CValue();
 public: 
	//User C´tor
	CValue(DataClass dataClass, short arrayEntries, short nScaling, bool bIsFloat, bool bInterpretedValue);	
	//Copy C´tor
	CValue(const CValue& x);
	//D´tor
	~CValue(){delete[] m_aValue; deleteAllInterInfo();}
private:
//--------------------------------------------------------------------------------
//Datamember
//--------------------------------------------------------------------------------
	vector <CInterInfo*> m_vValueInterInfo;		//Vector that saves all interpretation of the values
	vector <CInterInfo*> m_vFaultInterInfo;		//Vector that saves all interpretation of the fault
	short		m_nScaling;
	DataClass	m_DataClass;
	short		m_sArrayEntries;	
	
	double *	m_aValue;
	CString		m_sValueInter;
							
	int			m_nFault;	
	CString		m_sFaultInter;
	
	bool		m_bIsFloat;
	bool		m_bInterpretedValue;	
	bool		m_bValueInvalid;	
public:
//--------------------------------------------------------------------------------
//Methods
//--------------------------------------------------------------------------------
	short		getNbOfArrayEntries(void){return m_sArrayEntries;}
	CString		getAllDataAsString(void);
	
	void		addFaultInterInfo(short nFault, CString sFault);
	void		addValueInterInfo(double dValue, CString sValue);
	void		deleteAllInterInfo(void);	//Have to be called in D´tor deletes dynamicly allocated Space...
};

CValue Implementierung:
Code:
#include ".\value.h"

CValue::CValue() : m_DataClass(simple),
				   m_sArrayEntries(1),
				   m_sValueInter(""),
				   m_nFault(0),				   
				   m_sFaultInter(""),
				   m_nScaling(1),
				   m_bValueInvalid(false),
				   m_bInterpretedValue(false)
{
	m_aValue = new double[m_sArrayEntries];
	initArray();
}
//------------------------------------------------------------------------------------------------------------------------------------------------------
CValue::CValue(DataClass dataClass, short arrayEntries, short nScaling, bool bIsFloat, bool bInterpretedValue) :	

	m_DataClass(dataClass),
	m_sArrayEntries(arrayEntries),
	m_sValueInter(""),
	m_sFaultInter(""),
	m_nFault(0),
	m_nScaling(nScaling),
	m_bIsFloat(bIsFloat),
	m_bValueInvalid(false),
	m_bInterpretedValue(bInterpretedValue)
{
	m_aValue = new double[arrayEntries];
	initArray();
}
//------------------------------------------------------------------------------------------------------------------------------------------------------
CValue::CValue(const CValue& x) :
					
	m_DataClass(x.m_DataClass),
	m_sArrayEntries(x.m_sArrayEntries),
	m_sValueInter(x.m_sValueInter),
	m_sFaultInter(x.m_sFaultInter),
	m_nFault(x.m_nFault),
	m_nScaling(x.m_nScaling),
	m_bValueInvalid(x.m_bValueInvalid),
	m_bInterpretedValue(x.m_bInterpretedValue)
{
	m_aValue = new double[x.m_sArrayEntries];
	memcpy(m_aValue, x.m_aValue, sizeof(x.m_aValue));
}
//------------------------------------------------------------------------------------------------------------------------------------------------------
bool CValue::setValue(double dValue, short index)
{
	m_bValueInvalid = false;
	bool returnValue(true);
	dValue = dValue / m_nScaling;
	if(index < m_sArrayEntries)
		m_aValue[index] = dValue;
	else
		returnValue = false;
	if(m_bInterpretedValue)
		InterValue();
	return returnValue;
}
//------------------------------------------------------------------------------------------------------------------------------------------------------
CString	CValue::getAllDataAsString()
{	
	CString returnValue = "";
	if(!m_bValueInvalid)
	{	
		CString	temp = "";		
		for(short i(0); i < m_sArrayEntries; i++)
		{
			temp.Format("%lf", m_aValue[i]);
			returnValue += temp;
		}		
		if(m_DataClass == inter)
		{
			returnValue +=  m_sFaultInter;
			temp.Format("%lf", m_nFault);
			returnValue +=  temp;
		}
	}else
	{
		returnValue = "data corrupted";
	}		
	return returnValue;
}
//------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------
void CValue::addFaultInterInfo(short nFault, CString sFault)
{
	m_vFaultInterInfo.push_back(new CInterInfo(nFault, sFault));
}
//------------------------------------------------------------------------------------------------------------------------------------------------------
void CValue::addValueInterInfo(double dValue, CString sValue)
{
	m_vValueInterInfo.push_back(new CInterInfo(dValue, sValue));
}
//------------------------------------------------------------------------------------------------------------------------------------------------------
void CValue::deleteAllInterInfo(void)
{
	std::vector<int>::size_type i = m_vFaultInterInfo.size();
	if( i != 0)	
		for(i; i >= 0; --i)
		{
			if(m_vFaultInterInfo[i] != NULL)
				delete m_vFaultInterInfo[i];
		}
	m_vFaultInterInfo.clear();
		
	i = m_vValueInterInfo.size();
	if(i != 0)
		for(i; i >= 0; --i)
		{
			if(m_vValueInterInfo[i] != NULL)
				delete m_vValueInterInfo[i];
		}
	m_vValueInterInfo.clear();	
}

Die einzelnen Variablen definitionen:
(Hab hierbei mal die Komplexen und Geschützten Datentypen mal weggelassen...)
Code:
#pragma once
#include "var.h"

//------------------------------------------------------------------------------------------------------------------------------------------------------
class CSimpleDataType : public CVar
{
private:

public:
	CSimpleDataType(void);
	CSimpleDataType(CString VarName, AddrType AddrTypeOfVar, long AddressOfVar, 
						short Scaling, short NumberOfArrayEntries, bool bIsFloat, bool bInterpretedValue);
	virtual ~CSimpleDataType(void);
};
//------------------------------------------------------------------------------------------------------------------------------------------------------
class CSchar : public CSimpleDataType
{

private:

	static const short NeededBytesPerValue;

public:
	CSchar();
	CSchar(CString VarName, AddrType AddrTypeOfVar, long AddressOfVar, short NumberOfArrayEntries);
	//~CSchar();
	bool InterpretRawData(void);
};
//------------------------------------------------------------------------------------------------------------------------------------------------------
class CTBool: public CSimpleDataType
{

private:

	static const short NeededBytesPerValue;

public:
	CTBool();
	CTBool(CString VarName, AddrType AddrTypeOfVar, long AddressOfVar, short NumberOfArrayEntries);
	//~CTBool();
	bool InterpretRawData(void);
};
Variablen implementierung:
Code:
#include ".\simpledatatype.h"

const short CSchar::NeededBytesPerValue			= 1;
const short CSint::NeededBytesPerValue			= 2;
const short CSlong::NeededBytesPerValue			= 4;
const short CTBool::NeededBytesPerValue			= 1;
const short CTSrBool::NeededBytesPerValue		= 1;
const short CTModulation::NeededBytesPerValue	= 2;
const short CUchar::NeededBytesPerValue			= 1;
const short CUint::NeededBytesPerValue			= 2;
const short CUlong::NeededBytesPerValue			= 4;
const short CTIte::NeededBytesPerValue			= 2;
const short CTState::NeededBytesPerValue		= 1;
const short CNSR_Time::NeededBytesPerValue		= 1;

//----------------------------------------------------------------------------------------------------------------------------------------------
//C´tor definitions
//----------------------------------------------------------------------------------------------------------------------------------------------
CSimpleDataType::CSimpleDataType(void)
{
}
//--------------------------------------------------------------------------------
CSimpleDataType::~CSimpleDataType(void)
{
	delete m_Value;
}
//--------------------------------------------------------------------------------
CSimpleDataType::CSimpleDataType(CString VarName, AddrType AddrTypeOfVar, long AddressOfVar, 
									short Scaling, short NumberOfArrayEntries, bool bIsFloat, bool bInterpretedValue) :
	CVar(VarName, AddrTypeOfVar, AddressOfVar)
{
	m_Value = new CValue(simple, NumberOfArrayEntries, Scaling, bIsFloat, bInterpretedValue);
}
//--------------------------------------------------------------------------------
CSchar::CSchar(CString VarName, AddrType AddrTypeOfVar, long AddressOfVar, short NumberOfArrayEntries) :
	CSimpleDataType(VarName, AddrTypeOfVar, AddressOfVar, 1, NumberOfArrayEntries, false, false)
{
}
//--------------------------------------------------------------------------------
CTBool::CTBool(CString VarName, AddrType AddrTypeOfVar, long AddressOfVar, short NumberOfArrayEntries) :
	CSimpleDataType(VarName, AddrTypeOfVar, AddressOfVar, 1, NumberOfArrayEntries, false, true)
{
}
//--------------------------------------------------------------------------------
bool CTBool::InterpretRawData(void)
{
	bool returnValue(false);
	short neededArrayEntries = (m_Value->getNbOfArrayEntries() * NeededBytesPerValue + 1); //The device also returns the commando
	short startPos = 2;
	if(getAddrType() == addrSym) //Falls symbolisch, dann wird die Adresse der Variable zurück geliefert
	{
		neededArrayEntries += 2;
		startPos += 2;
	}
	if(m_abRawData[0] == neededArrayEntries)
	{
		int receivedValue;
		
		for(short i(0); i < m_Value->getNbOfArrayEntries(); i++)
		{
			receivedValue = m_abRawData[startPos + i * NeededBytesPerValue + 0];
			m_Value->setValue(receivedValue, i); //The Function scales the Value!
			returnValue = true;
		}		
	}else
	{
		m_Value->invalidateValues();
	}	
	return returnValue;
}

Wäre euch echt dankbar wenn sich jemand die Mühe machen würde das hier durch zu ackern und mir vielleicht sagen kann woran es liegt^^
Würd mir schon reichen wenn mir jemand sagen könnte worauf Excel mehr achtet als nen C++ Client.

Danke im Vorraus

Grüße RuFF
 
Zuletzt bearbeitet:
Hallöchen,

bei meiner dll handelt es sich um einen COM-InProc Server der nach standard erstellt wurde.
Die dll an sich läuft, auch unter VBA.
Ich kann z.B. hergehen und in dem COM InProc Server die Stellen wo die Konstruktoren aufgerufen werden ausdokumentieren
und es läuft einwandfrei durch erkennt die Devices und sended Telegramme auf den Bus!
Erst wenn versucht wird Objekte der oben genannten Klassen zu erstellen stürzt Excel ab, also wenn ich die Stelle wieder einfüge...

Aber eigentlich sellt die dll doch nur einen Einsprungpunkt dar, oder?
Wenn ich einmal in die Interfaces komme, ist es dem Client doch egal was wie benutzt wird, oder?
Ich will darauf hinaus dass alles lüppt nur das instanzieren von polymorphen Objekten geht nicht.
Ich kann mir vorstellen dass das Problem irgendwo in den Klassen liegt, werde jetzt einfach mal hergehen und Funktionalität heraus nehmen wie z.B. Interpretations Informationen und mal schaun obs geht ;)

EDIT:

Also ich hab den Fehler weiter lokalisiert und werde es mal hier Formulieren:

Die Klasse CValue besitzt einen Member vom Typ double und zwar einen Pointer darauf,
da es Datentypen gibt die als Array vorliegen.
Dann bekommt mein Konstruktor übergeben wieviele Array Einträge der Datentyp hat!
Dann wird innerhalb des CValue Konstruktors via new dynamisch ein double array erzeugt und dem double Pointer zugewiesen!
Und wenn es sich um kein Array handelt also nbOfArrayEntries = 1 ist ->
gibts halt nene Array mit nur einem Element:

Code:
//Deklaration der Member-Variable in CValue.h:
double *	m_aValue;

//Zuweisung im Konstruktor von CValue:
m_aValue = new double[arrayEntries];

Wenn ich jetzt genau diese Stelle heraus nehme läuft das ganze auch mit VBA!
Die Variablen werden halt erzeugt nur können grad keine Weret aufgenommen werden weil es ja keine Value Variable gibt, aber ich bekomme die Variablen-Liste ohne jeden Fehler übergeben!

Also ist die Frage inzwischen:

Wie kann ich in einem Konstruktor dynamisch ein Array anlegen, so scheints ja nicht zu gehen...
Was mich wundert ist dass es unter dem C++ Client ohne jede Beanstandung!

Grüße
RuFF
 
Zuletzt bearbeitet:
Hi also ArrayEntries hat entweder den Wert > 1 oder = 1
Niemals 0 oder ähnliches!
Der wird in VBA nicht gesetzt, sondern aus einer Datei ausgelesen.
Also wenn in der Datei kein Array gesetzt ist setz ich 1 ansonsten setz ich den in der Datei angegebenen Wert in [] Klammern...
 
Zurück