ut0mem.h, ut0mem.c:

  Implement ut_realloc
lexyy.c, pars0lex.l:
  Start using ut_malloc, ut_free, ut_realloc in pars0lex.l and lexyy.c; mem_realloc was broken; eliminate possible memcpy(NULL, ..., 0) from string_append()
parent 4a7b9fda
......@@ -57,6 +57,37 @@ ut_free(
/*====*/
void* ptr); /* in, own: memory block */
/**************************************************************************
Implements realloc. This is needed by /pars/lexyy.c. Otherwise, you should not
use this function because the allocation functions in mem0mem.h are the
recommended ones in InnoDB.
man realloc in Linux, 2004:
realloc() changes the size of the memory block pointed to
by ptr to size bytes. The contents will be unchanged to
the minimum of the old and new sizes; newly allocated mem­
ory will be uninitialized. If ptr is NULL, the call is
equivalent to malloc(size); if size is equal to zero, the
call is equivalent to free(ptr). Unless ptr is NULL, it
must have been returned by an earlier call to malloc(),
calloc() or realloc().
RETURN VALUE
realloc() returns a pointer to the newly allocated memory,
which is suitably aligned for any kind of variable and may
be different from ptr, or NULL if the request fails. If
size was equal to 0, either NULL or a pointer suitable to
be passed to free() is returned. If realloc() fails the
original block is left untouched - it is not freed or
moved. */
void*
ut_realloc(
/*=======*/
/* out, own: pointer to new mem block or NULL */
void* ptr, /* in: pointer to old block or NULL */
ulint size); /* in: desired size */
/**************************************************************************
Frees in shutdown all allocated memory not freed yet. */
void
......
......@@ -636,9 +636,9 @@ Linux.
#include "mem0mem.h"
#include "os0proc.h"
#define malloc(A) mem_alloc(A)
#define free(A) mem_free(A)
#define realloc(P, A) mem_realloc(P, A, __FILE__, __LINE__)
#define malloc(A) ut_malloc(A)
#define free(A) ut_free(A)
#define realloc(P, A) ut_realloc(P, A)
#define exit(A) ut_error
#define YY_INPUT(buf, result, max_size) pars_get_lex_chars(buf, &result, max_size)
......@@ -655,16 +655,16 @@ string_append(
const char* str, /* in: string to be appended */
ulint len) /* in: length of the string */
{
if (stringbuf == NULL) {
stringbuf = malloc(1);
stringbuf_len_alloc = 1;
}
if (stringbuf_len + len > stringbuf_len_alloc) {
if (stringbuf_len_alloc == 0) {
stringbuf_len_alloc++;
}
while (stringbuf_len + len > stringbuf_len_alloc) {
stringbuf_len_alloc <<= 1;
}
stringbuf = stringbuf
? realloc(stringbuf, stringbuf_len_alloc)
: malloc(stringbuf_len_alloc);
stringbuf = realloc(stringbuf, stringbuf_len_alloc);
}
memcpy(stringbuf + stringbuf_len, str, len);
......
......@@ -58,9 +58,9 @@ Linux.
#include "mem0mem.h"
#include "os0proc.h"
#define malloc(A) mem_alloc(A)
#define free(A) mem_free(A)
#define realloc(P, A) mem_realloc(P, A, __FILE__, __LINE__)
#define malloc(A) ut_malloc(A)
#define free(A) ut_free(A)
#define realloc(P, A) ut_realloc(P, A)
#define exit(A) ut_error
#define YY_INPUT(buf, result, max_size) pars_get_lex_chars(buf, &result, max_size)
......@@ -77,16 +77,16 @@ string_append(
const char* str, /* in: string to be appended */
ulint len) /* in: length of the string */
{
if (stringbuf == NULL) {
stringbuf = malloc(1);
stringbuf_len_alloc = 1;
}
if (stringbuf_len + len > stringbuf_len_alloc) {
if (stringbuf_len_alloc == 0) {
stringbuf_len_alloc++;
}
while (stringbuf_len + len > stringbuf_len_alloc) {
stringbuf_len_alloc <<= 1;
}
stringbuf = stringbuf
? realloc(stringbuf, stringbuf_len_alloc)
: malloc(stringbuf_len_alloc);
stringbuf = realloc(stringbuf, stringbuf_len_alloc);
}
memcpy(stringbuf + stringbuf_len, str, len);
......
......@@ -165,6 +165,88 @@ ut_free(
os_fast_mutex_unlock(&ut_list_mutex);
}
/**************************************************************************
Implements realloc. This is needed by /pars/lexyy.c. Otherwise, you should not
use this function because the allocation functions in mem0mem.h are the
recommended ones in InnoDB.
man realloc in Linux, 2004:
realloc() changes the size of the memory block pointed to
by ptr to size bytes. The contents will be unchanged to
the minimum of the old and new sizes; newly allocated mem
ory will be uninitialized. If ptr is NULL, the call is
equivalent to malloc(size); if size is equal to zero, the
call is equivalent to free(ptr). Unless ptr is NULL, it
must have been returned by an earlier call to malloc(),
calloc() or realloc().
RETURN VALUE
realloc() returns a pointer to the newly allocated memory,
which is suitably aligned for any kind of variable and may
be different from ptr, or NULL if the request fails. If
size was equal to 0, either NULL or a pointer suitable to
be passed to free() is returned. If realloc() fails the
original block is left untouched - it is not freed or
moved. */
void*
ut_realloc(
/*=======*/
/* out, own: pointer to new mem block or NULL */
void* ptr, /* in: pointer to old block or NULL */
ulint size) /* in: desired size */
{
ut_mem_block_t* block;
ulint old_size;
ulint min_size;
void* new_ptr;
printf("Calling realloc with size %lu\n", size);
if (ptr == NULL) {
printf("ptr was NULL, calling malloc\n");
return(ut_malloc(size));
}
if (size == 0) {
ut_free(ptr);
return(NULL);
}
block = (ut_mem_block_t*)((byte*)ptr - sizeof(ut_mem_block_t));
ut_a(block->magic_n == UT_MEM_MAGIC_N);
old_size = block->size - sizeof(ut_mem_block_t);
printf("Old size was %lu\n", old_size);
if (size < old_size) {
min_size = size;
} else {
min_size = old_size;
}
new_ptr = ut_malloc(size);
if (new_ptr == NULL) {
return(NULL);
}
/* Copy the old data from ptr */
ut_memcpy(new_ptr, ptr, min_size);
printf("Copying %lu bytes to new_ptr\n", min_size);
ut_free(ptr);
return(new_ptr);
}
/**************************************************************************
Frees in shutdown all allocated memory not freed yet. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment