- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
template<typename T>
static ALWAYS_INLINE void FormatLogMessageAndPrintW(
const char* channelName,
const char* functionName,
LOGLEVEL level,
const char* message,
bool timestamp,
bool ansi_color_code,
bool newline,
const T& callback)
{
char buf[512];
char* message_buf = buf;
int message_len;
if ((message_len = FormatLogMessageForDisplay(message_buf,
sizeof(buf), channelName, functionName,
level,
message, timestamp,
ansi_color_code, newline)) > (sizeof(buf) - 1))
{
message_buf = static_cast<char*>(std::malloc(message_len + 1));
message_len = FormatLogMessageForDisplay(message_buf,
message_len + 1, channelName, functionName,
level, message, timestamp, ansi_color_code, newline);
}
if (message_len <= 0)
return;
// Convert to UTF-16 first so unicode characters display correctly.
// NT is going to do it anyway...
wchar_t wbuf[512];
wchar_t* wmessage_buf = wbuf;
int wmessage_buflen = countof(wbuf) - 1;
if (message_len >= countof(wbuf))
{
wmessage_buflen = message_len;
wmessage_buf = static_cast<wchar_t*>
(std::malloc((wmessage_buflen + 1) * sizeof(wchar_t)));
}
wmessage_buflen = MultiByteToWideChar(CP_UTF8, 0, message_buf,
message_len, wmessage_buf, wmessage_buflen);
if (wmessage_buflen <= 0)
return;
wmessage_buf[wmessage_buflen] = '\0';
callback(wmessage_buf, wmessage_buflen);
if (wmessage_buf != wbuf)
{
std::free(wbuf); // <=
}
if (message_buf != buf)
{
std::free(message_buf);
}
}
#копипаста #молока
Надо было использовать scoped_pointer или как его зовут?
Автор решил, что если буфер укладывается в 512 байтиков, для него нецелесообразно дёргать дорогостоящий malloc, хватит и стека. А если не уложится, можно и malloc дёрнуть.
И вся печаль в реализации: он решил в стеке предварительно выделить буфера по 512 байтиков, а позже, если не хватит, маллокать и переставлять указатель. Багор возникает при освобождении памяти: нужно узнать, какой буфер использовался: из стека или из маллока. И вот тут в одну из веток прокралась опечатка.
https://www.rsdn.org/article/cpp/smartptr.xml
Как их использовать в данном реальном примере?
Всё! И анализатор не ругнется, и память освободится автоматически!
З.Ы. Есть, boost::small_vector<uint8_t, 512>
Это правда заслуживает отдельной статьи и каких-то сложных рассуждений?
(чтобы по запросу "PVS" первой ссылкой выдавалось говнокод и goatse.)
> PVS is a mechanized environment for formal specification and verification. PVS consists of a specification language, a large number of predefined theories, a type checker, an interactive theorem prover that supports the use of several decision procedures and a symbolic model checker, various utilities including a code generator and a random tester, documentation, formalized libraries, and examples that illustrate different methods of using the system in several application areas. By exploiting the synergy between a highly expressive specification language and powerful automated deduction, PVS serves as a productive environment for constructing and maintaining large formalizations and proofs. See the description page for a summary of the features of PVS, and the documentation page for full details.
Оно еще на LISP написано, не то что Coq
Ну почему не сделать отдельный указатель под выделенный буфер и отдельный указатель под активный буфер? И потом тупо работаем с active (в котором или стековый или allocated) и в конце free(allocated) без всяких там условий...
Нет блядь, будем экономить на спичках...
И это я ещё в код не всматривалась и не искала off by one и целочисленные переполнения которые там по-любому есть...
https://a.d-cd.net/a476409s-960.jpg
Да, не каждый справится с первого раза.