char* x[] oder char** x initialisieren.



  • Hallo,

    ich baue eine Klasse, die folgende private member hat (haben soll)...

    private:
    	char* m_OsNames[11];
    	char** m_OsNames2;
    

    Hier habe ich einen Array von Zeigern auf char und kann damit dann
    mehrere "Strings" zuweisen. Ich weiß, das ich folgendes machen kann...

    char* OSNames[] ={"7 (NT Version 6.1)"	,
    		          "Vista (NT Version 6.0)",
    		          "Server 2003 (NT Version 5.2)",
    		          "XP (NT Version 5.1)",
    		          "XP (NT Version 5.1)",
    		          "2000 (NT Version 5.0)",
    		          "ME",
    		          "NT4",
    		          "98",
    		          "95 OSR 2",
    		          "NT3",
    		          "95"};
    

    mit "char** m_OsNames2;" habe ich einen Zeiger auf einer Zeiger auf einen char's

    und kann dann das machen...

    m_OsNames2 = new char*[11];
    m_OsNames2 = OSNames;
    

    im Destruktor mache ich dann das ....

    CSystem::~CSystem()
    {
    	delete m_OsNames2;
    }
    

    Wieso geht aber nicht...

    m_OsNames[]={"..","..",".."}
    

    also den m_OsNames erst so deklarieren und dann initialisieren.

    Gruß
    Franky



  • Eine Initialisierung kann nur mit einer Deklarierung daher gehen. Alles andere ist eine Zuweisung. Die = {...} Syntax funktioniert nur mit Initialisierungen.

    Und wieso benutzt du nicht std::string?



  • char* OSNames[] ={"7 (NT Version 6.1)"	,
    		          "Vista (NT Version 6.0)",
    		          "Server 2003 (NT Version 5.2)",
    		          "XP (NT Version 5.1)",
    		          "XP (NT Version 5.1)",
    		          "2000 (NT Version 5.0)",
    		          "ME",
    		          "NT4",
    		          "98",
    		          "95 OSR 2",
    		          "NT3",
    		          "95"};
    

    Stringliterale sind konstant, dementsprechend ist das nicht erlaubt. Du brauchst ein Array von const char*s.

    m_OsNames2 = new char*[11];
    m_OsNames2 = OSNames;
    

    Du forderst Speicher an und überschreibst dann die Adresse mit OSNames? Macht keinen Sinn und erzeugt ein Speicherleck.

    CSystem::~CSystem()
    {
    	delete m_OsNames2;
    }
    

    Ein new[] angeforderter Speicherbereich muss mit delete[] freigegeben werden.
    Ein überhaupt nicht mit new erzeugter Speicherbereich (OSNames) darf überhaupt nicht manuell freigegeben werden.

    Du solltest std::string und std::vector benutzen, besonders solange du in Zeigern und ähnlichem noch nicht fit bist.



  • Warum sollte er statische Strings auf den Heap packen? Besonders wenn die Klasse öfters initialisiert wird, soll er die schön in der .rdata lassen. 😉



  • Hi,

    ich heabe das jetzt so gemacht...

    Header....

    #include <windows.h>
    
    #ifdef SYSTEM_EXPORTS
    #define SYSTEM_API __declspec(dllexport)
    #else
    #define SYSTEM_API __declspec(dllimport)
    #endif
    
    typedef int (__cdecl *DLLPROC)(LPWSTR);
    const int MAX_OS_NAMES = 11;
    const int MAX_FK_NAMES = 10;
    
    // This class is exported from the System.dll
    class SYSTEM_API CSystem {
    	//constructor and desctructor section
    public:
    	CSystem(void);
    	~CSystem();
    	//member section started
    private:
    	const char* m_OsNames[MAX_OS_NAMES];
    	const char* m_FkNames[MAX_FK_NAMES];
    public:
    	void OSVersion(char* lpOsVersion);
    };
    
    CSystem* System = NULL;
    SYSTEM_API void  __stdcall CreateInstance(void);
    SYSTEM_API void  __stdcall RealOSVersion(char* lpOsVersion);
    

    und dann die cpp Datei...

    #include "stdafx.h"
    #include "System.h"
    
    CSystem::CSystem()
    {
    	m_OsNames[0] = "7 (NT Version 6.1)";
    	m_OsNames[1] = "Vista (NT Version 6.0)";
        m_OsNames[2] = "Server 2003 (NT Version 5.2)";
    	m_OsNames[3] = "XP (NT Version 5.1)";
    	m_OsNames[4] = "XP (NT Version 5.1)";
    	m_OsNames[5] = "2000 (NT Version 5.0)";
    	m_OsNames[6] = "ME";
    	m_OsNames[7] = "NT4";
    	m_OsNames[8] = "98";
    	m_OsNames[9] = "95 OSR 2";
    	m_OsNames[10] = "NT3";
    	m_OsNames[11] = "95";
    
    	m_FkNames[0] = "GetLocaleInfoEx";
        m_FkNames[1] = "GetLargePageMinimum";
        m_FkNames[2] = "GetDLLDirectory";
        m_FkNames[3] = "GetNativeSystemInfo";
        m_FkNames[4] = "ReplaceFile";
        m_FkNames[5] = "OpenThread";
        m_FkNames[6] = "GetThreadPriorityBoost";
        m_FkNames[7] = "IsDebuggerPresent";
        m_FkNames[8] = "GetDiskFreeSpaceEx";
        m_FkNames[9] = "ConnectNamedPipe";
        m_FkNames[10] = "Beep";
    	return;
    }
    
    CSystem::~CSystem()
    {
    }
    
    void  CSystem::OSVersion(char* lpOsVersion)
    {
    	HINSTANCE hLib = LoadLibrary(TEXT("KERNEL32.DLL")); 
        if ( hLib == NULL ){ 
            return; 
        } 
    	for(int i=0;i<MAX_FK_NAMES;i++)
    	{
    		DLLPROC Proc = (DLLPROC) GetProcAddress(hLib,m_FkNames[i]); 
    		if(Proc !=NULL) break;
    		switch(i)
    		{
    			case 0: 
    				lpOsVersion = const_cast<char*>(m_OsNames[1]);
    				break;
    			case 1:
    				lpOsVersion = const_cast<char*>(m_OsNames[2]);
    				break;
    			case 2:
    				lpOsVersion = const_cast<char*>(m_OsNames[3]);
    				break;
    			default:
    				lpOsVersion = "Unkown OS";
    		}
    						;
    	}
    	FreeLibrary(hLib); 
    }
    
    SYSTEM_API void __stdcall CreateInstance(void)
    {
    	if(System == NULL)
    	{
    		System = new CSystem;	    
    	}
    }
    
    SYSTEM_API void __stdcall RealOSVersion(char* lpOsVersion)
    {
    	if(System != NULL)
    	{
    		System->OSVersion(lpOsVersion);
    	}
    }
    

    Da char* [] ein Array von Zeigern auf char sind, wird es im Header deklariert und dann initialisert. Da nicht mit new angelegt auch kein delete.

    char* muß ich machen da die Klasse in einer VBA DLL und Strings in VBA wenn in einer DLL übergeben auf einen LPSTR (...char*) abegebildert werden.

    Gruß
    Frank


Anmelden zum Antworten