[asterisk-commits] kpfleming: branch 1.4 r176216 - /branches/1.4/main/utils.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Feb 16 15:10:39 CST 2009
Author: kpfleming
Date: Mon Feb 16 15:10:38 2009
New Revision: 176216
URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=176216
Log:
fix a flaw in the ast_string_field_build() family of API calls; these functions made no attempt to reuse the space already allocated to a field, so every time the field was written it would allocate new space, leading to what appeared to be a memory leak.
Modified:
branches/1.4/main/utils.c
Modified: branches/1.4/main/utils.c
URL: http://svn.digium.com/svn-view/asterisk/branches/1.4/main/utils.c?view=diff&rev=176216&r1=176215&r2=176216
==============================================================================
--- branches/1.4/main/utils.c (original)
+++ branches/1.4/main/utils.c Mon Feb 16 15:10:38 2009
@@ -1256,24 +1256,49 @@
int index, const char *format, va_list ap1, va_list ap2)
{
size_t needed;
-
- needed = vsnprintf(mgr->pool->base + mgr->used, mgr->space, format, ap1) + 1;
+ size_t available;
+ char *target;
+
+ /* if the field already has space allocated, try to reuse it;
+ otherwise, use the empty space at the end of the current
+ pool
+ */
+ if (fields[index][0] != '0') {
+ target = (char *) fields[index];
+ available = strlen(fields[index]);
+ } else {
+ target = mgr->pool->base + mgr->used;
+ available = mgr->space;
+ }
+
+ needed = vsnprintf(target, available, format, ap1) + 1;
va_end(ap1);
- if (needed > mgr->space) {
- size_t new_size = mgr->size * 2;
-
- while (new_size < needed)
- new_size *= 2;
-
- if (add_string_pool(mgr, new_size))
- return;
-
- vsprintf(mgr->pool->base + mgr->used, format, ap2);
- }
-
- fields[index] = mgr->pool->base + mgr->used;
+ if (needed > available) {
+ /* if the space needed can be satisfied by using the current
+ pool (which could only occur if we tried to use the field's
+ allocated space and failed), then use that space; otherwise
+ allocate a new pool
+ */
+ if (needed <= mgr->space) {
+ target = mgr->pool->base + mgr->used;
+ } else {
+ size_t new_size = mgr->size * 2;
+
+ while (new_size < needed)
+ new_size *= 2;
+
+ if (add_string_pool(mgr, new_size))
+ return;
+
+ target = mgr->pool->base + mgr->used;
+ }
+
+ vsprintf(target, format, ap2);
+ }
+
+ fields[index] = target;
mgr->used += needed;
mgr->space -= needed;
}
More information about the asterisk-commits
mailing list