Improved talloc.c
andreas moroder
claudiamoroder at st-ulrich.suedtirol.net
Sat Aug 25 05:32:15 GMT 2001
Hello Tim,
here my talloc.patch.
There could be a way to improve realloc very much but I MUST be shure that
talloc_realloc is only used with memory allocated with talloc_.
If you could tell me that this is granted I will do the necessary changes.
This way I could also solve the size bug in talloc_memdup.
By
Andreas
--- talloc.c Sat Aug 25 06:52:58 2001
+++ talloc.new Sat Aug 25 07:07:39 2001
@@ -1,4 +1,4 @@
-/*
+/*
Unix SMB/Netbios implementation.
Version 3.0
Samba temporary memory allocation functions
@@ -35,10 +35,21 @@
#include "includes.h"
+// If there are systems that must allign on a bigger boundary then 8
+// the constant 3 must be changed
+
+#define TALLOC_SHIFT 3
+#define TALLOC_NEW_ALLIGN ( 1 << TALLOC_SHIFT )
+
+static unsigned short tc_offset;
+
+
+
/* initialise talloc context. */
TALLOC_CTX *talloc_init(void)
{
TALLOC_CTX *t;
+ unsigned short l, off;
t = (TALLOC_CTX *)malloc(sizeof(*t));
if (!t) return NULL;
@@ -46,6 +57,13 @@
t->list = NULL;
t->total_alloc_size = 0;
+// Maybe there is a way to calculate the alligned size of this structure
+// at compile time
+
+ l=sizeof(struct talloc_chunk);
+ for(tc_offset=0;l!=0; tc_offset+=TALLOC_NEW_ALLIGN)
+ l=l>>TALLOC_SHIFT;
+
return t;
}
@@ -57,15 +75,14 @@
if (size == 0) return NULL;
- p = malloc(size);
- if (!p) return p;
-
- tc = malloc(sizeof(*tc));
+ tc = malloc(tc_offset+size);
if (!tc) {
free(p);
return NULL;
}
+ p=(void *)tc;
+ p+=tc_offset;
tc->ptr = p;
tc->size = size;
tc->next = t->list;
@@ -78,7 +95,8 @@
/* a talloc version of realloc */
void *talloc_realloc(TALLOC_CTX *t, void *ptr, size_t size)
{
- struct talloc_chunk *tc;
+ struct talloc_chunk *tc, *prev,*next;
+ void *p;
/* size zero is equivalent to free() */
if (size == 0)
@@ -88,16 +106,37 @@
if (ptr == NULL)
return talloc(t, size);
+ prev=NULL;
for (tc=t->list; tc; tc=tc->next) {
if (tc->ptr == ptr) {
- ptr = realloc(ptr, size);
+ next=tc->next;
+ ptr = realloc(tc, size+tc_offset);
if (ptr) {
+ tc=ptr;
+ p=(void *)tc;
+ p+=tc_offset;
+ tc->ptr = p;
t->total_alloc_size += (size - tc->size);
tc->size = size;
- tc->ptr = ptr;
+
+ if(prev) {
+ prev->next=tc;
+ } else {
+ t->list=tc;
+ }
+ ptr=p;
+ } else {
+ if(prev) {
+ prev->next=next;
+ } else {
+ t->list=next;
+ }
+ // should I free the data pointed by original tc ?
+ // If I don't I am buggy but consistent with the
rest of samba ;)
}
return ptr;
}
+ prev=tc;
}
return NULL;
}
@@ -112,7 +151,6 @@
while (t->list) {
c = t->list->next;
- if (t->list->ptr) free(t->list->ptr);
free(t->list);
t->list = c;
}
@@ -155,7 +193,8 @@
if (!newp)
return 0;
-
+// BUG !?! What if size is bigger then the original size ??
+// p will go over the boundary and may crash
memcpy(newp, p, size);
return newp;
More information about the samba-technical
mailing list