LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (https://www.linuxquestions.org/questions/linux-general-1/)
-   -   in linux malloc() initializes to zero. (https://www.linuxquestions.org/questions/linux-general-1/in-linux-malloc-initializes-to-zero-843577/)

chaitanyajun12 11-10-2010 11:32 PM

in linux malloc() initializes to zero.
 
#include<stdio.h>
#include<stdlib.h>

int main()
{
char *ptr;
ptr = (char *)malloc(10);
printf("%d...",(int)*ptr);
}

when i run this program, malloc is intializing the allocated memory to
zero. Whats the reason?

Dark_Helmet 11-11-2010 12:14 AM

From man malloc (emphasis added):
Quote:

malloc() allocates size bytes and returns a pointer to the allocated
memory. The memory is not cleared. If size is 0, then malloc()
returns either NULL, or a unique pointer value that can later be suc‐
cessfully passed to free().
No, malloc is not initializing your memory to anything. Each byte can be 0 just as easily as anything else. Perhaps the memory block allocated to your process was never used by another process. Perhaps the last process that used it set the memory to 0's before finishing. Perhaps a block of all 0's meant something to the last process that used the memory.

You cannot conclude that malloc() is doing something because you observe a result you do not expect. Your logic would require that malloc() actually intentionally scramble memory before giving it to a process just to make sure the process got random junk.

macemoneta 11-11-2010 12:22 AM

Security, so you can't peek at previously allocated memory from another process. You can get non-zero memory if it was previously freed by your process. See:

http://www.mail-archive.com/freebsd-.../msg37534.html

Dark_Helmet 11-11-2010 12:30 AM

Hmmmmm.... well, perhaps I'm wrong in a roundabout way, but I could swear I've been burned by first-allocation, uninitialized, non-zero junk memory before.

Regardless, I've developed the habit of zero-filling my memory reservations. So maybe I just didn't notice the change.

chaitanyajun12 11-11-2010 05:12 AM

i got the same program on two systems it was just 0.
That was the reason i asked it?

i have one doubt..
As soon as process terminates its memory gets freed up. right?
After freeing is it initialized to zero?

estabroo 11-11-2010 05:14 AM

If you want it guaranteed to be zero after allocation just use calloc instead of malloc. If another process used that memory you'll get some value other than what it placed there I'm guessing 0 is the wipe value of choice for that, but you can malloc space you previously malloc'd in the same program and not get 0 values

chaitanyajun12 11-12-2010 01:24 AM

how to malloc the space we malloc'd in the same program.
Plz give an example.

Chaitanya.

estabroo 11-12-2010 07:16 AM

malloc a large chunk, write stuff to it, some pattern easy to spot (store the pointer you got)
free it
malloc another chunk (you can compare the pointer to the original)

most likely that second malloc will fall across the same memory and if the OS hasn't remapped the underlying physical memory you'll usually get the same chunk or something that falls across the space of the original chunk.

Code:

#include<stdio.h>
#include<stdlib.h>

int main(int argc, char* argv[]) {

        char* ptr;
        char* ptr_a;
        int  i;

        ptr_a = malloc(100000);
        if (ptr_a != NULL) {
                ptr = ptr_a;
                for (i=0; i < 100000; i++) {
                        ptr[i] = 0x5A;
                }
                free(ptr_a);
                ptr_a = malloc(100000);
                printf("ptr %p, ptr_a %p\n", ptr, ptr_a);
                for (i=0; i < 100000; i++) {
                        if (ptr_a[i] == 0x5A) {
                                break;
                        }
                }
                if (i != 100000) {
                        printf("found pattern at %d\n", i);
                }
        }
}


johnsfine 11-12-2010 08:52 AM

estabroo has answered this, so maybe my post is redundant. But I'm not sure estabroo's would be understood by those that didn't already know the answer:

Quote:

Originally Posted by Dark_Helmet (Post 4155439)
Hmmmmm.... well, perhaps I'm wrong in a roundabout way, but I could swear I've been burned by first-allocation, uninitialized, non-zero junk memory before.

No, you were right the first time. The fact that malloc doesn't zero fill the memory means you can't rely on the memory being zero filled. Of course you also can't rely on the memory not being zero filled.

Linux zero fills the memory when it creates new pages of anonymous memory for your task. The first allocations (from malloc) by a simple program almost certainly are first uses of memory that was zero filled by Linux. But maybe some library routine has injected some startup code into the things that happen before main(). That is common in C++. I'm not sure what might happen in pure C. Maybe that startup code allocates and frees some memory. Maybe that is the memory you get on what you think is the first call to malloc. So even when calling malloc before any free has been called (by your code) I would not want to trust that the memory is still zero filled.

As estabroo explained, once you are getting memory from malloc that your own process previously gave back with free, you are getting left over contents of what was freed.

Quote:

Originally Posted by Dark_Helmet (Post 4155420)
Your logic would require that malloc() actually intentionally scramble memory before giving it to a process just to make sure the process got random junk.

BTW, a common and useful debugging aid (that is turned on by default when you debug in Visual Studio) is that malloc does actually fill memory with a specific nonzero pattern. So code that depends on uninitialized memory being zero will break when you debug it in Visual Studio. Quite a lot of otherwise hard to find bugs are caught that way, so it is a very useful feature.

Dark_Helmet 11-12-2010 07:22 PM

@johnsfine:

Thank you for clearing that up. I didn't completely follow the thought process in the email exchange you linked. In brief, I thought it was trying to say that when a process was spawned, a virtual memory space was created, that the virtual memory space was zero-filled, and therefore it would be impossible to get junk on a first-malloc(). Regardless, I feel like I should go review memory space terminology. I get the feeling I'm still missing something.

Quote:

BTW, a common and useful debugging aid (that is turned on by default when you debug in Visual Studio) is that malloc does actually fill memory with a specific nonzero pattern.
Although I don't use the Visual Studio stuff, I implement something similar at times. I read in some book the suggestion to fill dynamically allocated memory with a recognizable pattern rather than 0's or pure random data. So, I will sometimes use a couple of preprocessor "DEBUG" ifdefs that define either 0x00000000 or 0xDEADBEEF as the pattern to initialize dynamic memory. It works too. You open a debugger, add a couple watches, and facepalm when you see a permutation of 0xDEADBEEF in the data the program is croaking on. Good stuff.

chaitanyajun12 11-13-2010 12:08 AM

thank u all ...really helpful stuff.!
Thank u so much.

johnsfine 11-13-2010 07:25 AM

Quote:

Originally Posted by Dark_Helmet (Post 4157265)
@johnsfine:

Thank you for clearing that up. I didn't completely follow the thought process in the email exchange you linked.

You mean the email exchange macemoneta linked.

Quote:

In brief, I thought it was trying to say that when a process was spawned, a virtual memory space was created, that the virtual memory space was zero-filled, and therefore it would be impossible to get junk on a first-malloc().
That is what it was saying and is roughly true. I was trying to point out one of the complications that you might not be able to be sure a malloc is necessarily a first-malloc (sure it isn't reusing space your own process's internal startup code already used and released).


All times are GMT -5. The time now is 06:46 AM.