Char-Array als Parameter, Zugriff per sizeof
-
SammyRukka schrieb:
- Als string antworten geht ja nicht, also 'Speicherplatz' ersteinmal als Pointer mitgeben.
- Aber gleich als TCHAR[], weil 'GetModuleFileNameEx' das sowiso so braucht und ein String von Haus aus zu klein sein könnte.ich frage mich, was für eine art von string du meinst... und was TCHAR ist?
Jetzt macht 'GetModuleFileNameEx' aber ein Problem, weil sizeof vermutlich 1 liefert:
nicht unbedingt 'wahrscheinlich'.
Lokal würde das ganze funktionieren:
lokal?
TCHAR l_prozessPfad[MAX_PATH] = TEXT("<unknown>"); GetModuleFileNameEx(pi.hProcess, hMod, l_prozessPfad, sizeof(l_prozessPfad)/sizeof(TCHAR));btw. wenn TCHAR nur ein einfaches define auf chars ist, kannst du dir das /sizeof(TCHAR) sparen. sizeof(char) ist nämlich 1. immer.
vertraue sizeof niemals nicht unüberlegt. (siehe unten)
Wie mache ich das, ohne fest 'MAX_PATH' mitzugeben?!
entweder so, wie du schon gesagt hast, oder du sagst dem compiler einfach, dass du ein array von der größe MAX_PATH übergeben willst. wenn sich MAX_PATH nicht so wirklich ändern soll, ist das auch ganz passabel:
//vielleicht in einen namespace packen? namespace my_globals { const int MAX_PATH; //} void foo (char (&str)[MAX_PATH]) //die referenz ist nötig, sonst funktioniert sizeof nicht wegen 4.2/1 { //... }allerdings spricht dann auch nichts dagegen, gleich MAX_PATH an die funktion zu übergeben, die du aufrufst.
-
Kuggugg !
Um MAX_PATH brauchst du dir nicht so sehr den Kopf zu zerbrechen, denn
das ist schon in u.a. windef.h definiert:#define MAX_PATH 260#include <windows.h> // Hat auch windef.h included. #include <iostream> using namespace std; bool deine_funktion( HANDLE hProcess, MODULE hModule, char* buf ) { if ( ! GetModuleFileNameEx( hProcess, hModule, (LPTSTR)buf, sizeof( buf ) )) { return false; } else return true; } int main() { ... // Die Version für knauserige Bytefuchser: #ifdef UNICODE char buf[ 2 * MAX_PATH ] = '\0'; #else char buf[ MAX_PATH ] = '\0'; #endif // Aber eigentlich kommts ja nicht auf 260 Byte drauf an, // dann kann man gleich schreiben: char buf[ 2 * MAX_PATH ] = '\0'; // Und ist auf der sicheren Seite. if ( deine_funktion( hProcess, hModule, char* buf ) ) { cout << buf << endl; } else { cout << "Failed on GetModuleFileNameEx" << endl; // Fehlerbehandlung ... // DWORD dw = GetLastError ... } ... return 0; }
-
thx - ich hab jetzt die standard-lösung benutzt und die Größe einfach auch noch mitgegeben.
-
@queer_boy: Über TCHAR mußt du dir nicht unbedingt den Kopf zerbrechen, das wird je nach Compilereinstellungen umgewandelt in 'char' (ANSI-Umgebung) oder 'wchar_t' (UNICODE-Umgebung). Wer mit WinAPI arbeitet, hantiert fast ständig damit herum.
@Sammy und proggingmania:
sizeof() liefert nur dann die korrekte Größe, wenn du das Array als echtes Array vorliegen hast. Sobald du nur noch den Zeiger auf den Array-Anfang hast, kommst du nicht mehr an die Größenangaben heran - deshalb solltest du entweder die Vorbedingung setzen, daß vor dem Aufruf eine bestimmte Größe verfügbar ist oder die verfügbare Größe mitliefern.
-
Ist char buf[ MAX_PATH ] kein echtes Array ?

-
proggingmania schrieb:
Ist char buf[ MAX_PATH ] kein echtes Array ?

Doch, aber p_prozessPfad halt nicht ... und ich denke, darauf wollte er hinweisen.
Leider ist die "implizite Array-Information des Compilers" nicht über Funktionsgrenzen hinweg transportierbar .. (aber das hast Du ja eigentlich auch selbst schon geschrieben).Gruß,
Simon2.
-
CStoll schrieb:
@Sammy und proggingmania:
sizeof() liefert nur dann die korrekte Größe, wenn du das Array als echtes Array vorliegen hast. Sobald du nur noch den Zeiger auf den Array-Anfang hast, kommst du nicht mehr an die Größenangaben heran - deshalb solltest du entweder die Vorbedingung setzen, daß vor dem Aufruf eine bestimmte Größe verfügbar ist oder die verfügbare Größe mitliefern.Und ich finde, dass ich stolz darauf sein, kann, dass ich das selbst bemerkt habe, als ich sah, dass nur der erste Buchstabe kopiert wurde (wg. sizeof = 1 beim Poniter)

-
SammyRukka schrieb:
Und ich finde, dass ich stolz darauf sein, kann, dass ich das selbst bemerkt habe, als ich sah, dass nur der erste Buchstabe kopiert wurde (wg. sizeof = 1 beim Poniter)

Das hört sich für mich nach einem anderen Problem an, nämlich dem, das du für
dein TCHAR* p_prozessPfad keinen Speicherplatz mit malloc reserviert hast
Wie kommst du eigentlich auf TCHAR ?
Gucke mal hier:DWORD GetModuleFileNameEx( HANDLE hProcess, // handle to the process HMODULE hModule, // handle to the module LPTSTR lpFilename, // buffer that receives the path DWORD nSize // size of the buffer );Das ist nen LPTSTR.
-
Ein LPTSTR ist ein "Long Pointer to T String" also ein Zeiger (Pointer) auf eine Kette (String) von TCHAR

-
proggingmania schrieb:
Ist char buf[ MAX_PATH ] kein echtes Array ?

Doch, das schon - aber in der aufgerufenen Funktion hast du 'nur'
char* bufund das ist kein Array mehr
@Sammy: sizeof() auf einen Zeiger liefert normalerweise mehr als 1 (typisch sind 4 Byte).
-
CStoll schrieb:
... und das ist kein Array mehr

...Ja, das ist in der Tat Blödsinn

-
CStoll schrieb:
@Sammy: sizeof() auf einen Zeiger liefert normalerweise mehr als 1 (typisch sind 4 Byte).
Ja, ist wohl korrekt, es waren glaube ich auch 2 Zeichen, aber zumindest vieeeel zu kurz und viel zu gut zu meiner Vermutung passend, als das ich das nicht anerkennen würde.

Auf TCHAR bin ich durch einer andere, vorher aufgerufene Funktion gekommen.proggingmania schrieb:
Das hört sich für mich nach einem anderen Problem an, nämlich dem, das du für
dein TCHAR* p_prozessPfad keinen Speicherplatz mit malloc reserviert hast
Warum sollte ich da Speicherplatz reservieren. Ich habe das Array als Lokale und kann es halt nicht direkt an eine aufgerufene Methode übergeben. Der Speicherplatz ist ja trotzdem korrekt reserviert.
.....*offtopic* :p Ich finde Java besser, bastle aber trotzdem gern mit C++ herum! /offtopic

-
Simon2 schrieb:
Leider ist die "implizite Array-Information des Compilers" nicht über Funktionsgrenzen hinweg transportierbar
mit dem trick, den ich beschrieben habe, schon. allerdings hat CStoll recht, sobald es ein pointer wird.. futsch

-
queer_boy schrieb:
Simon2 schrieb:
Leider ist die "implizite Array-Information des Compilers" nicht über Funktionsgrenzen hinweg transportierbar
mit dem trick, den ich beschrieben habe, schon....
Oha, den hatte ich noch nicht gesehen und kannte ihn auch nicht.... nice.
Spätestens mit einem typedef wirds dann "schick":typedef char PATH[256]; typedef char FILENAME[15]; void foo (PATH const& str) { cout << "path: " << str << " " << sizeof(str) << "\n"; } void foo (FILENAME const& str) { cout << "filename: " << str << " " << sizeof(str) << "\n"; } int main () { PATH p = "path"; foo(p); FILENAME f = "FileName"; foo(f); return 0; }
Ich hätte darauf gewettet, dass das nicht funktioniert ... weil ich nicht auf die Referenze gekommen bin. Spätestens hier wird eine "const&" statt einer Kopie wichtig...Gruß,
Simon2.
-
Lasst Euch die Arraylänge doch gleich vom Compiler mit in die Funktion übergeben

template< size_t N > void foo( char const ( & str )[ N ] ) { cout << "path: " << str << " " << N << "\n"; } int main() { char path[256]; char *ptr; foo(path); // ok foo(ptr); // error }