Q about Pointers

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
amirsadig

Q about Pointers

Post 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.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Q about Pointers

Post 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).
amirsadig

Re:Q about Pointers

Post 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.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:Q about Pointers

Post 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
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Schol-R-LEA

Re:Q about Pointers

Post 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)
proxy

Re:Q about Pointers

Post 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
Schol-R-LEA

Re:Q about Pointers

Post 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.
Post Reply