malloc spielt verrückt
-
Huhu,
Ich hab folgendes problem:
Ich allokiere zuerst für einen LPWSTR speicherplatz,
Setze den Speicher auf 0,
Kopiere dann einen Teil eines anderen LPWSTR in diesen,
führe ein paar berechnungen durch,
und will dann für einen weiteren LPWSTR speicherplatz allokieren.An dieser Stelle bekomme ich von malloc immer nur NULL zurück...
Hier mal der Code, vielleicht sieht das ganze etwas durcheinander aus aber naja...
void Protokoll::open() { LPWSTR cmdline = GetCommandLine(); //Programmpfad holen cmdline++; //Das erste Zeichen ist ein " das muss weg //Hier hole ich mir einen Pointer auf den letzten Backslash vor der //.exe datei LPWSTR buffer = wcsrchr(cmdline, L'\\'); int bufferLen = wcslen(buffer); //Die Länge des Dateinamens mit .exe int cmdlineLen = wcslen(cmdline); //Die Länge des Pfades mit .exe int pathLen = cmdlineLen - bufferLen; //Länge des Pfades ohne .exe LPWSTR path = (LPWSTR)malloc(sizeof(wchar_t)*pathLen); //malloc geht ZeroMemory(path, sizeof(path)); //geht auch //Kopieren des Programmpfades ohne die .exe Datei //z.B. L"c:\programme\MeinProgramm" ohne "\Programm.exe" wcsncpy_s(path, sizeof(wchar_t)*pathLen, cmdline, pathLen); //Gewünschte Unterpfade LPWSTR errorSubPath = L"\\log\\errorLog.txt"; LPWSTR statusSubPath = L"\\log\\statusLog.txt"; //Längen der 2 erstellten Unterpfade int errorSubLen = wcslen(errorSubPath); int statusSubLen = wcslen(statusSubPath); //Längen des Pfades + Unterpfad int errorLen = pathLen + errorSubLen; int statusLen = pathLen + statusSubLen; //allokieren des speichers für Pfad + Unterpfad //Die beiden geben NULL zurück LPWSTR errorPath = (LPWSTR)malloc(sizeof(wchar_t)*errorLen); LPWSTR statusPath = (LPWSTR)malloc(sizeof(wchar_t)*statusLen);
Das beinahe lustige ist:
Wenn ich die beiden ZeilenLPWSTR errorPath = (LPWSTR)malloc(sizeof(wchar_t)*errorLen); LPWSTR statusPath = (LPWSTR)malloc(sizeof(wchar_t)*statusLen);
oberhalb von
wcsncpy_s(path, sizeof(wchar_t)*pathLen, cmdline, pathLen);
schreibe (natürlich mit den ganzen Deklarationen die dafür nötig sind) funktionieren diese beiden aufrufe von malloc.
Also was mache ich falsch?
Danke schonmal im voraus.
-
Du machst zwei Sachen falsch:
1. Du hast die Doku zu strncpy_s nicht gelesen; vor allen nicht die Bedeutung des zweiten Parameters...
2. Aus diesem Grunde überschreibst Du an dieser Stelle Speicher; dies führt dann zu einem Fehler in malloc... (da hier die Heap-Corruption festgestellt wird)Korrekt wäre der Code so (hab auch gleich noch ein paar andere Unschönheiten beseitigt):
LPWSTR cmdline = GetCommandLine(); //Programmpfad holen cmdline++; //Das erste Zeichen ist ein " das muss weg //Hier hole ich mir einen Pointer auf den letzten Backslash vor der //.exe datei LPWSTR buffer = wcsrchr(cmdline, L'\\'); size_t bufferLen = wcslen(buffer); //Die Länge des Dateinamens mit .exe size_t cmdlineLen = wcslen(cmdline); //Die Länge des Pfades mit .exe size_t pathLen = cmdlineLen - bufferLen; //Länge des Pfades ohne .exe LPWSTR path = (LPWSTR)malloc(sizeof(wchar_t)*(pathLen+1)); //malloc geht //Kopieren des Programmpfades ohne die .exe Datei //z.B. L"c:\programme\MeinProgramm" ohne "\Programm.exe" wcsncpy_s(path, pathLen+1, cmdline, pathLen); //Gewünschte Unterpfade LPCWSTR errorSubPath = L"\\log\\errorLog.txt"; LPCWSTR statusSubPath = L"\\log\\statusLog.txt"; //Längen der 2 erstellten Unterpfade size_t errorSubLen = wcslen(errorSubPath); size_t statusSubLen = wcslen(statusSubPath); //Längen des Pfades + Unterpfad size_t errorLen = pathLen + errorSubLen; size_t statusLen = pathLen + statusSubLen; //allokieren des speichers für Pfad + Unterpfad //Die beiden geben NULL zurück LPWSTR errorPath = (LPWSTR)malloc(sizeof(wchar_t)*(errorLen+1)); LPWSTR statusPath = (LPWSTR)malloc(sizeof(wchar_t)*(statusLen+1));
-
Moment mal ... C++ und malloc + rohe C-Strings?
-
Icematix schrieb:
Moment mal ... C++ und malloc + rohe C-Strings?
...funktioniert wunderbar, wenn man es richtig macht, wolltest du sicher sagen. Da bin ich ganz deiner Meinung!
-
Klar funktioniert es. Aber wieso sollte irgendwer sowas machen wollen?
-
hustbaer schrieb:
Klar funktioniert es. Aber wieso sollte irgendwer sowas machen wollen?
Ein Grund wäre, wenn man die Zeigerauch zum freigeben an ein C Modul übergibt.
Ansonsten ist dieser ganze malloc Kram überflüssig und macht den Code absolut unleserlich. Einfach Arrays auf dem Stack mit _MAX_PATH anlegen und gut ists.
-
Martin Richter schrieb:
Ansonsten ist dieser ganze malloc Kram überflüssig und macht den Code absolut unleserlich. Einfach Arrays auf dem Stack mit _MAX_PATH anlegen und gut ists.
Nanana... von dem Rate ich aber drigend ab... _MAX_PATH ist 260, was in NTFS gerade mal ungefähr die Länge *eines* Pfadteiles ist... es mag zwar eine Begrenzung der CRT sein, wer aber "flexible" Programme schreiben will, sollte die Pfade immer dynamisch zusammenbauen.
Es gibt wirklich Pfade die wesentlich länger als 260 Zeichen sind.Also entweder std::string/wstring/CString oder eben malloc bzw. "new". Aus meiner Sicht spricht da überhaupt nichts dagegen, sondern ist zu empfehlen!
-
Jochen Kalmbach schrieb:
Martin Richter schrieb:
Ansonsten ist dieser ganze malloc Kram überflüssig und macht den Code absolut unleserlich. Einfach Arrays auf dem Stack mit _MAX_PATH anlegen und gut ists.
Nanana... von dem Rate ich aber drigend ab... _MAX_PATH ist 260, was in NTFS gerade mal ungefähr die Länge *eines* Pfadteiles ist... es mag zwar eine Begrenzung der CRT sein, wer aber "flexible" Programme schreiben will, sollte die Pfade immer dynamisch zusammenbauen.
Es gibt wirklich Pfade die wesentlich länger als 260 Zeichen sind. (ok, der Explorer kommt damit auch nicht zurrecht, aber das ist für mich kein Argument)Also entweder std::string/wstring/CString oder eben malloc bzw. "new". Aus meiner Sicht spricht da überhaupt nichts dagegen, sondern ist zu empfehlen!
-
Natürlich spricht nichts gegen dynamische Puffer für Pfade.
Aber bitte nicht alles zu Fuss machen, und bitte schon garnicht mit malloc.