Dynamic char* allocation, malloc and free.

L

Lawrie

Hi,

I am fairly new to C programming and would like to ask a little help
with the following problem.

I am writing a simple ring buffer, implemented as an array of char *.

char* ringbuffer[BUFFLEN];

When I receive a new message (of type char*) I need to make a copy of
the contents of the string in case anyone tampers the original char* (I
have done this by writing a safe string copy routine that takes into
account that the original string may not be null terminated and my
attempt to malloc enough space for the copy may fail).

All well and good so far. I have allocated space for my copy of the
original string and inserted it into my ring buffer at the correct
position.

ringbuffer[end] = message;

When I pop my message off of the ring buffer I do the following

char* message = ringbuffer[start];

Now, here is where I have a problem. I may not be able to process the
whole of my message. In this case I have to replace whatever remains of
the string back in the ringbuffer. I do this by shifting the message
pointer (array index) along by the number of bytes I have processed.

int processed_bytes = dosomething(message);

if (processed_bytes < strlen(message)) {
/* increment message poinmter
message = message + processed_bytes)
}
else {
/* Message processing complete, free memory */
free(message);
}

Will me call to free() free all of the memory allocated to message
during the malloc() call if I have subsequently incremented the message
pointer or will I get a memory leak?

Many thanks for any help.

Lawrie
 
R

Richard Bos

Lawrie said:
int processed_bytes = dosomething(message);

if (processed_bytes < strlen(message)) {
/* increment message poinmter
message = message + processed_bytes)
}
else {
/* Message processing complete, free memory */
free(message);
}

Will me call to free() free all of the memory allocated to message
during the malloc() call if I have subsequently incremented the message
pointer or will I get a memory leak?

If the pointer you pass to free() isn't the same pointer you got from
malloc() (or realloc(), or calloc()), you get undefined behaviour. This
means that in theory it might work; in practice, you'll most likely get
a segfault.
You could get around this by adding a field to your array to remember
the original pointer, or the offset; or by malloc()ing some new memory
and copying the remaining message to it; or, probably the best solution,
by moving the end of the message to the beginning (optionally followed
by realloc()).

Richard
 
S

SM Ryan

# Hi,
#
# I am fairly new to C programming and would like to ask a little help
# with the following problem.
#
# I am writing a simple ring buffer, implemented as an array of char *.
#
# char* ringbuffer[BUFFLEN];

# Now, here is where I have a problem. I may not be able to process the
# whole of my message. In this case I have to replace whatever remains of
# the string back in the ringbuffer. I do this by shifting the message
# pointer (array index) along by the number of bytes I have processed.

Use two pointers.

struct{char *base,*curr;} ringbuffer[BUFFLEN];

ringbuffer.base is assigned the mallocked block address and
ringbuffer.base is initialised to this. Advance .curr. When
you're done free .base.
 
C

Chris Croughton

Now, here is where I have a problem. I may not be able to process the
whole of my message. In this case I have to replace whatever remains of
the string back in the ringbuffer. I do this by shifting the message
pointer (array index) along by the number of bytes I have processed.

int processed_bytes = dosomething(message);

if (processed_bytes < strlen(message)) {
/* increment message poinmter
message = message + processed_bytes)
}
else {
/* Message processing complete, free memory */
free(message);
}

Will me call to free() free all of the memory allocated to message
during the malloc() call if I have subsequently incremented the message
pointer or will I get a memory leak?

So you pass to free() a pointer which is not the same as the one
returned by malloc()? That will not have good results, free() has no
way of getting back to the original pointer, so it will be undefined
behaviour (if you're lucky it will crash in the free(), if you're
unlucky all sorts of weird behaviour may result at some later time).

Basically you need to preserve the pointer returned by malloc(). One
way of doing that might be to save an offset with each pointer in
your ring buffer. Another might be to have a single offset variable
which is set to non-zero when the head message has been partially
processed. Another might be to put a single nul character at the start
of each message, with the message itself following and the pointer in
the ring buffer pointing to the start of the message data (assuming that
data doesn't contain a nul), and on releasing the storage scan backwards
for the nul character at the start.

Which method is best for your application is up to you, but hopefully
this may give you ideas (there are probably many other ways to achieve
it).

Chris C
 
L

Lawrence Kirby

# Hi,
#
# I am fairly new to C programming and would like to ask a little help
# with the following problem.
#
# I am writing a simple ring buffer, implemented as an array of char *.
#
# char* ringbuffer[BUFFLEN];

# Now, here is where I have a problem. I may not be able to process the
# whole of my message. In this case I have to replace whatever remains of
# the string back in the ringbuffer. I do this by shifting the message
# pointer (array index) along by the number of bytes I have processed.

Use two pointers.

struct{char *base,*curr;} ringbuffer[BUFFLEN];

ringbuffer.base is assigned the mallocked block address and
ringbuffer.base is initialised to this. Advance .curr. When
you're done free .base.


You don't need a curr pounter for every element of the ringbuffer, just
the one you're reading from. So this can be a single variable separate
from the array.

Lawrence
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Alternative to Malloc in C 0
malloc 40
malloc and maximum size 56
Malloc question 9
malloc 11
malloc and free 11
Dynamic and Static Allocation 5
array-size/malloc limit and strlen() failure 26

Members online

Forum statistics

Threads
474,164
Messages
2,570,898
Members
47,439
Latest member
shasuze

Latest Threads

Top