Page 1 of 1

Q about Pointers

Posted: Sat Jun 12, 2004 5:27 am
by amirsadig
As we know using pointer in kernel is the heart of it. but it need a good knowledge and praxis.

I have notice that I should initialize all pointers. for example

Code: Select all

struct foo {
void *some;
};

struct foo *foo1;
foo1 = (struct foo *)malloc(sizeof(struct foo));
if I tryed to make a condition on it like

Code: Select all

if(foo1->some == NULL)
 // do something
the kernel sometime crash (page fault). but if I initialize "foo1->some" with 0 then it work.

I think that when I use malloc it reserve only memory for the struct foo and do not zero it. therefor sometime the memory location of struct save an old value, which does this page fault (correct me if I am wrong).
I could solve it in kernel by initialize all pointers, but user program sometimes they forget that. I can use malloc to zero the memory, which it has reserved for an object.
is that a good solution? or simply kill the user process,when page fault occur, which does not included in user space address.

Re:Q about Pointers

Posted: Sat Jun 12, 2004 12:38 pm
by Candy
This is a FAQ. You don't zero the BSS section on loading your kernel. BSS contains all uninitialized data. Initialize the BSS section with zeroes as is required by the C standard. (note that this will automatically set those pointers to NULL).

Re:Q about Pointers

Posted: Sat Jun 12, 2004 1:31 pm
by amirsadig
in boot init code do zero bss ;D. I speek when using malloc or free function in kernel or user application, should I zero also the allocated memory or leave it to program to initialize.

Re:Q about Pointers

Posted: Sat Jun 12, 2004 2:22 pm
by Brendan
Hi,
amirsadig wrote: in boot init code do zero bss ;D. I speek when using malloc or free function in kernel or user application, should I zero also the allocated memory or leave it to program to initialize.
Memory obtained via malloc() needs to be cleared or initialized before use. There's another function like malloc called "calloc()" which will allocate an area and fill it with 0's for you.

BTW malloc() doesn't free memory because often the area is filled with actual data soon after malloc is called.


Cheers,

Brendan

Re:Q about Pointers

Posted: Sat Jun 12, 2004 6:11 pm
by Schol-R-LEA
While it is true that calloc() ensure that memory is always , it differs from malloc() only in that it takes an additional argument [tt]count[/tt], and allocates enough memory for [tt]count[/tt] objects of [tt]size[/tt] bytes. It is primarily used to allocate arrays, IIUC. More importantly, it is still necessary to implement it for the new system.

The easiest way to ensure that a block of memory is cleared is to use memset(). Fortunately, there are several example implementations available in the archives. Together with malloc(), it can be used to implement calloc() in a straightforward manner:

Code: Select all

void* calloc(size_t count, size_t size)
{
   size_t total;
   void* buf;
   
   total = count * size;  /* the number of elements * the size of the type */

   buf = malloc(total);  
   memset(buf, 0, total);
   return buf;
}
This is tested code, and can be used as is. I intentionally wrote it out rather than stuffing it into a one-liner to make it easier to read.

Implementations of memset() can be found in these threads:
Primary topic of thread
Reply #19 (note that there is a bug in this; 'CDL' should be 'CLD')
Reply #1 (same code as in previous example)
Primary topic of thread, several different implementations discussed, including a very simple one in portable C in reply#4 (most others use assembly, in whole or in part)

Re:Q about Pointers

Posted: Sun Jun 13, 2004 8:50 pm
by proxy
three things:

1: note that the mentioned calloc implementation is vulnerable to a integer overflow, in a real world implementation, this must be checked.

2: if the malloc fails in the mentioned calloc, then the memset will trash memory, that should also be checked.

i perfer to write calloc like this:

Code: Select all

void *calloc(size_t nmemb, size_t size) {
   /* we need to ensure this because we divide by this later */
   assert(nmemb != 0);

   void *ret = 0;
   size_t len = (nmemb * size);
   
   /* do some overflow checking.. */
   if (nmemb && size != (len / nmemb)) {
      /* there was an error, set errno or somthing! */
   } else if((ret = malloc(len)) != 0) {
      /* allocate it and zero it */
      memset(ret, 0, len);
   }
   
   return ret;
}
3: when you have a struct which you dynamically allocate and has pointers within the struct, either do one of 2 things..use calloc or explicitly zero all the members. malloc by definition has no need to zero memory and on a real machine it is likely not going to be zeroed by chance.

proxy

Re:Q about Pointers

Posted: Mon Jun 14, 2004 6:05 am
by Schol-R-LEA
Oh, you're right on all three points. And to think that I'm usually the one to point out this sort of mistake... ouch.