Здесь:
mergeWChar(msg, t);
msg
указывает на строковый литерал L"Ts is jut a phrase in order to test my function"
. Вы не можете изменить строковый литерал.
Вы хотите это:
inline void mergeWChar(wchar_t*& dest, const wchar_t* source) {
if (dest == nullptr) {
dest = const_cast<wchar_t*>(source);
return;
}
wchar_t *newdest = (wchar_t*)malloc((wcslen(dest) + wcslen(source) + 1) * sizeof *newdest);
wcscpy(newdest, dest); // the *_s functions are useless here
wcscat(newdest, source); // as you know that newdest point to
// a long enough buffer
dest = newdest;
}
Отказ от ответственности: здесь не делается проверка ошибок для краткости.
Источником проблемы является плохой дизайн функции mergeWChar
и сомнительное использование const_cast<wchar_t*>
, которое в основном позволяет назначить указатель на постоянную строку для обычного указателя, что затем позволяет изменить это постоянная память, которая в конечном итоге выходит из строя.
Однако есть проблема с этим дизайном: вы не можете освободить выделенную память, потому что указатель dest
не обязательно является указателем, который был получен через malloc
. Поэтому следующий дизайн лучше ИМО:
inline void mergeWChar(wchar_t*& dest, const wchar_t* source) {
int size = (dest ? wcslen(dest) : 0) + wcslen(source) + 1;
wchar_t *newdest = (wchar_t*)malloc(size * sizeof *newdest);
if (dest)
wcscpy(newdest, dest);
else
newdest[0] = 0;
wcscat(newdest, source);
dest = newdest;
}
Таким образом, нет никакого уродливого приведения и нет риска неконстантного указателя, указывающего на постоянную память, и вы можете быть уверены, что указатель, модифицированный mergeWChar
, может быть освобожден, несмотря ни на что. Стоимость в том, что вам нужно больше памяти.
Пример использования:
...
wchar_t* msg = nullptr;
wchar_t* t = L"BLA.BLA.BLA";
mergeWChar(msg, L"Ts is jut a phrase in order to test my function");
mergeWChar(msg, t);
...
free(msg);
...