[си] не пойму кусок кода [closed]

feliks28

Код - это кусок одной из найденных в инете реализаций функции CommandLineToArgvW, отвечающий за то, чтобы если не указаны параметры, вернуть массив с одним элементом: путем к файлу.
091         LPWSTR  *lpArgvW = NULL;
092
093 if ( !lpCmdLineW || !*lpCmdLineW )
094 {
095 CHAR szFileName[MAX_PATH];
096
097 DWORD dwResult = GetModuleFileNameA( NULL, szFileName, MAX_PATH );
098
099 if ( dwResult && dwResult < MAX_PATH )
100 {
101 int cchNeeded = MultiByteToWideChar( CP_ACP, 0, szFileName, -1, NULL, 0 );
102

103 lpArgvW = (LPWSTR *)GlobalAlloc( 0, cchNeeded * sizeof(WCHAR) + sizeof(LPWSTR) );

104
105 if ( lpArgvW )
106 {

107 lpArgvW[0] = (LPWSTRlpArgvW + 1);

108
109 MultiByteToWideChar( CP_ACP, 0, szFileName, -1, lpArgvW[0], cchNeeded );
110 *pNumArgs = 1;
111 }
112 else
113 SetLastError( ERROR_OUTOFMEMORY );
114 }
115 }

Что мне непонятно:
103: Причем тут sizeof(LPWSTR) ? В cchNeeded уже же хранится <длина строки> + 1. Этого недостаточно?
107: Почему + 1 ?

Oper

Данный код может соответствовать стандарту C99. Больше про него ничего сказать нельзя

Oper

Почему + 1 ?
и действительно, почему ?

vall

а GetModuleFileNameW нету что-ли?

feliks28

Данный код может соответствовать стандарту C99. Больше про него ничего сказать нельзя
Код - это кусок одной из найденных в инете реализаций функции CommandLineToArgvW, отвечающий за то, чтобы если не указаны параметры, вернуть массив с одним элементом: путем к файлу.

feliks28

и действительно, почему ?
Если это сарказм то я его не понял...

Oper

Да лана, не принимай близко к сердцу. Это я так, в порядке флуда. Лезть в гугль (или еще куда-то) неохота.

feliks28

Я только сделал копипаст. Почему авторы этого кода им не воспользовались я не знаю.
Это, кстати, для меня момент несущественный, т.к. я в tchar'ы и без MultiByteToWideChar буду переписывать
Мне непонятно почему память под строку так хитро выделяется

bleyman

Очевидно же.
argv это, упрощённо, "char**", а на деле LPWSTR*, где LPWSTR в свою очередь является WCHAR*.
Короче, массив массивов это. Или массив указателей, как больше нравится. Поэтому чтобы передать туда единственную строчку, нужно выделить память под строчку плюс память под указатель на неё. Поэтому прибавляется эта шняга и поэтому же +1.

feliks28

Спасибо. Теперь все встало на свои места.

feliks28

А кстати, то что массив argv нужно нулевым указателем в последнем элементе закрывать - это распространяется только на случаи, когда argc > 1 ?
Зачем оно вообще надо?

feliks28

Почитал исходники MinGW'шного core c

The argument vector is always kept terminated with a @code{NULL} arg pointer, so it can be passed to @code{freeargv} at any time, or returned, as appropriate.
Так что в коде видимо следовало бы написать 2* sizeof(LPWSTR) и +2, и добавить lpArgvW[1] = NULL;
Но, честно говоря, я так и не понял зачем это нультерминирование надо, если есть argc.
Оставить комментарий
Имя или ник:
Комментарий: