3

Hello I use malloc() to generate a buffer like this where buffer is a char*

buffer = (char*)malloc(chunksize+1);
 for (k = 0; k < chunksize; k++) {
 buffer[k] = (char) (j+k);
 }

however, in debugger i can see the buffer[3] for example is the char i wrote in, but the buffer buffer is empty(a lot of spaces). But the second time I write stuff in the buffer after free(buffer), it shows the the content I wrote the first time, and overwrite it. Can anyone tell me why? Thank you!!

asked Feb 23, 2011 at 18:53
9
  • 1
    What's j? What's chunksize? And did you really say "write stuff in the buffer after free(buffer)"? Commented Feb 23, 2011 at 18:57
  • sorry my bad. It is in a loop, free the buffer in the end of the loop but i do malloc every time before writing like the code shown Commented Feb 23, 2011 at 19:00
  • 1
    don't do the two casts. they are redundant, at least, and the first one may even hide problems like forgetting to include the prototype. Commented Feb 23, 2011 at 21:41
  • Shouldn’t that be malloc((chunksize+1)*sizeof(char))? (I don’t know C, but that just looks wrong.) Commented Feb 23, 2011 at 22:03
  • sizeof(char) is always one, so drop the pointless part of multiplying by 1. Commented Feb 23, 2011 at 22:13

3 Answers 3

8

Generally speaking, malloc implementations work by getting a large chunk of memory from the OS, then sub-allocating bits of it when you ask for buffers. This is because getting memory from the OS is relatively slow.

As a security measure, your OS will give malloc blank memory (full of 0 or some other repeating value). You wouldn't want one process to be able to read the leavings of an unrelated process.

However, malloc has no such problems, because it only serves from that chunk to one process. It doesn't matter if you can see your own leavings (at least not from a security POV).

So what's happened is that you've malloced a buffer, and seen it initially blank. Then you've freed it and asked for "another" buffer, and malloc happens to have handed you the same memory again, this time containing the values you left in it.

This "coincidence" of getting the same memory twice isn't very unlikely, since there's a good reason for malloc to re-use recently-used memory where possible - it's more likely to be in cache.

You might think this doesn't matter to you, because normally you wouldn't read from newly-allocated memory. But it matters to malloc, because typically malloc keeps its own house-keeping data adjacent to the buffer. It also may matter if there's a cost associated with expelling memory from the cache - if you can be "tricked" into re-using the same memory over and over again, then this happens less.

answered Feb 23, 2011 at 18:59
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you. but why the chars are not written when I check the buffer from the debugger? I intent to write the buffer to a file right after. And when I read the content from the file, I get a lot of "32" which is space. but second time, it is acting normal.
@user512853: Hmm, I may have misunderstood the question. I thought you meant that you saw blank memory while your loop was executing, overwriting with your values (j, j+1, etc). Actual space characters (i.e. ASCII 32), as opposed to unprintable characters shown as blanks in the debug memory view, doesn't sound likely for uninitialized memory. When you write to file, are you definitely writing the same chunksize that you've filled in, and starting from the same address? Check what memory looks like just before you call fwrite.
I generate the buffer, then write the buffer to the file, free the buffer, malloc it again and repeat the previous steps. Later on, I read the file to a buffer and compare if the content is the same as I wrote before, one the first chunk is full of 32, other chunks are correct.
when I check the memory, the debugger is acting weired. I can see buffer[3] for example is the char I wrote in, but buffer is full of spaces
1

One problem might be that you try to print your char buffer with printf or equivalent? You are missing to assign

buffer[chunksize] = 0;

So your buffer is not well terminated. It may have anything behind that, e.g '\r'.

If on the other hand buffer doesn't represent a string for you, better use a different base type, probably unsigned char.

answered Feb 23, 2011 at 21:47

3 Comments

That should be buffer[chunksize] = '0円';. Although they may have the same bitwise representation, your intention is clearer when you use the appropriate literal.
This is nothing but a matter of taste. '0円' is nothing than another name for 0. I am more in favor of using the same 0 for all initializations.
Empty string: buffer[0] = '0円';
0

Your code is correct. The problem could be in some part of the code that you haven't shown if you are concerned that you overwrite some bad memory. For example, if buffer is a pointer to non-char array, in which case pointer arithmetic that you use will result in bad memory access (corruption). You can use the following program as a reference:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ()
{
 const size_t chunksize = 15;
 size_t k;
 char *buffer;
 buffer = malloc (chunksize + 1);
 memset (buffer, 0, chunksize + 1);
 for (k = 0; k < chunksize; ++k)
 {
 buffer[k] = '0' + (char)k + 49;
 }
 for (k = 0; k < chunksize; ++k)
 {
 printf ("%lu = %c\n", k, buffer[k]);
 }
 free (buffer);
 return 0;
}

Output:

0 = a
1 = b
2 = c
3 = d
4 = e
5 = f
6 = g
7 = h
8 = i
9 = j
10 = k
11 = l
12 = m
13 = n
14 = o
answered Feb 23, 2011 at 19:05

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.