G
Guest
I usually try to stay away from _alloca(). However, I'm considering using it
for a logging function. Our current logging function maintains its own
buffer which it grows to fit the string being logged. To work correctly in a
multi-threaded environment there are locks around the code which log the
string. We could remove the locks and just allocate on the heap, but then we
could run into heap contention and heap fragmentation. We could also just
keep the instance buffer in there along with the locks.
Another approach would be to use the stack to store the buffer, e.g.
_alloca. The problem is that I don't know the size the buffer needs to be.
The logging API is exposed via a method that allows for a variable number of
arguments (...) and we use _vsnprintf() to format the buffer. I don't want
to create an extremely large buffer to handle any possible input since that
could blow up our stack quite easily. So I'm wondering if _alloca() can be
chained as follows:
#define ALLOCA_BLOCK_SIZE (1024)
void EventLogLogger::LogArg(short type, long severityLevel, const char
*format, va_list args)
{
char *buffer;
int size = 0;
while (true)
{
size += ALLOCA_BLOCK_SIZE;
buffer = (char *) _alloca(ALLOCA_BLOCK_SIZE);
if (_vsnprintf(buffer + this->_len + 2, size - this->_len + 2, format,
args) >= 0)
break;
}
strcpy(buffer, this->_application);
buffer[this->_len] = ':';
buffer[this->_len + 1] = ' ';
OutputDebugString(buffer);
}
So the chaining above allocates the same block size each time (1024) but I'm
assuming buffer points to a block of memory whose size is 'size' (n * 1024).
Is this correct? This code appears to work. What it does is simply output
the string to the debug monitor, prepending <application: > where application
is a string supplied to the constructor of my class.
In reading the docs for _alloca() it mentions something about not being able
to use _alloca() in exception handling clauses, though it then says you can
use it from within an EH routine. What does this mean? I just can't have it
in the catch clause but I can call a function from the catch clause which
uses _alloca()?
for a logging function. Our current logging function maintains its own
buffer which it grows to fit the string being logged. To work correctly in a
multi-threaded environment there are locks around the code which log the
string. We could remove the locks and just allocate on the heap, but then we
could run into heap contention and heap fragmentation. We could also just
keep the instance buffer in there along with the locks.
Another approach would be to use the stack to store the buffer, e.g.
_alloca. The problem is that I don't know the size the buffer needs to be.
The logging API is exposed via a method that allows for a variable number of
arguments (...) and we use _vsnprintf() to format the buffer. I don't want
to create an extremely large buffer to handle any possible input since that
could blow up our stack quite easily. So I'm wondering if _alloca() can be
chained as follows:
#define ALLOCA_BLOCK_SIZE (1024)
void EventLogLogger::LogArg(short type, long severityLevel, const char
*format, va_list args)
{
char *buffer;
int size = 0;
while (true)
{
size += ALLOCA_BLOCK_SIZE;
buffer = (char *) _alloca(ALLOCA_BLOCK_SIZE);
if (_vsnprintf(buffer + this->_len + 2, size - this->_len + 2, format,
args) >= 0)
break;
}
strcpy(buffer, this->_application);
buffer[this->_len] = ':';
buffer[this->_len + 1] = ' ';
OutputDebugString(buffer);
}
So the chaining above allocates the same block size each time (1024) but I'm
assuming buffer points to a block of memory whose size is 'size' (n * 1024).
Is this correct? This code appears to work. What it does is simply output
the string to the debug monitor, prepending <application: > where application
is a string supplied to the constructor of my class.
In reading the docs for _alloca() it mentions something about not being able
to use _alloca() in exception handling clauses, though it then says you can
use it from within an EH routine. What does this mean? I just can't have it
in the catch clause but I can call a function from the catch clause which
uses _alloca()?