Hey guys (and girls),
I have been reading this list for sometimebut this is the first time I'm actually posting something.This might fit better in a C\C++ forum but I base my question on the notion that I confidence in my C skills and that there is an underlying cause for the choice of PHP developers to save Bucket data the way they do.If I am mistaken in posting this here please let me know.
I came to ponder this when working with hash functions (zend_hash_find,zend_hash_add) and I saw that zend_hash_add (macro for _zend_hash_add_or_update) accepts pData as void * but is usually passed an address of a pointer like in:
zend_class_entry *ce;zend_hash_add(CG(class_table), "class_name",class_length+1, &ce);
pData is in turn memcpy'd into a Bucket's pData element which is also void *, passing the &ce suggests that what will get memcpy'd will be the contents of &ce which is in turn the address pointed to by ce, the address of a zend_class_entry struct, this suggests that the Bucket's pData element though marked as void * actually servs as a void ** (since it points to an adress which should be dereferenced as a pointer).
I validated this by looking at zend_hash_find which accepts pData as void **, this time pData is to hold the address for the data retrieved by zend_hash_find, this time I noticed the function call to be :
zend_class_entry **ce;zend_hash_find(CG(class_table), "class_name", class_length+1, (void **) &ce);
and the data assigned to pData is :*pData = Bucket->pData;
By my logic by setting *pData I am setting the data held at the address in pData itself which is &ce, this sets ce to point to an address of Bucket->pData which as I established earlier is used as a void **.
I may be missing some basic understanding in pointers but I am pretty confident that this is not the case and thus I am asking is there a specific reason to use this sort of 'trickery' instead of of explicitly using void *, I fail to see the harm in Bucket->pData being a pointer to the data itself and the needed casts to be done instead of the current situtaiton where it points to another address.
Thank you for any light you can shed on this.
Sorry for the formatting, I'm not sure why the newlines got removed since I formatted this much more nicely, any reason why it happened? I could repost it in a more readble format
From: jb_jeff@hotmail.com
To: internals@lists.php.net
Date: Thu, 16 Sep 2010 09:56:59 +0000
Subject: [PHP-DEV] Understanding the benefits of handling Bucket data in PHP's HashTablesHey guys (and girls),
I have been reading this list for sometimebut this is the first time I'm actually posting something.This might fit better in a C\C++ forum but I base my question on the notion that I confidence in my C skills and that there is an underlying cause for the choice of PHP developers to save Bucket data the way they do.If I am mistaken in posting this here please let me know.
I came to ponder this when working with hash functions (zend_hash_find,zend_hash_add) and I saw that zend_hash_add (macro for _zend_hash_add_or_update) accepts pData as void * but is usually passed an address of a pointer like in:
zend_class_entry *ce;zend_hash_add(CG(class_table), "class_name",class_length+1, &ce);
pData is in turn memcpy'd into a Bucket's pData element which is also void *, passing the &ce suggests that what will get memcpy'd will be the contents of &ce which is in turn the address pointed to by ce, the address of a zend_class_entry struct, this suggests that the Bucket's pData element though marked as void * actually servs as a void ** (since it points to an adress which should be dereferenced as a pointer).
I validated this by looking at zend_hash_find which accepts pData as void **, this time pData is to hold the address for the data retrieved by zend_hash_find, this time I noticed the function call to be :
zend_class_entry **ce;zend_hash_find(CG(class_table), "class_name", class_length+1, (void **) &ce);
and the data assigned to pData is :*pData = Bucket->pData;
By my logic by setting *pData I am setting the data held at the address in pData itself which is &ce, this sets ce to point to an address of Bucket->pData which as I established earlier is used as a void **.
I may be missing some basic understanding in pointers but I am pretty confident that this is not the case and thus I am asking is there a specific reason to use this sort of 'trickery' instead of of explicitly using void *, I fail to see the harm in Bucket->pData being a pointer to the data itself and the needed casts to be done instead of the current situtaiton where it points to another address.
Thank you for any light you can shed on this.
Hi!
The bucket can store 2 types of data - either any random piece of data
(ARPD) or a pointer. When bucket with ARPD is created/deleted, the
memory storing ARPD is allocated/freed. When bucket holding a pointer is
created/freed, nothing special happens since the pointer is stored
inside the bucket.
zend_hash_find returns the pointer to the data stored, not the copy of
it (since you might want to modify it), that's the reason why it's
void** - it's pointer to the data, which is by itself either pointer
passed to hash or pointer to allocated piece for ARPD.
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227