creating nested arrays from C

From: Date: Tue, 12 Oct 1999 05:31:58 +0000
Subject: creating nested arrays from C
Groups: php.version4 
Request: Send a blank email to php-version4+get-5496@lists.php.net to get a copy of this message
Hi, I'm trying to create nested arrays (based on XML input parsed via Expat) in a C extension. Based on examples in the other code, I'm adding the arrays with zend_hash_update(). However, I've noticed some major weirdnesses. The same weirdnesses do not happen when I create multi-dimensional code via the php language, so I know it is at least _possible_. I would appreciate it if someone could point me in the right direction. thx. -dan The weirdness: * Depending on the key used, I sometimes get segfaults in zend_hash_add_or_update ( zend_hash.c:136). It looks like it trying to use a value from the wrong hash bucket. Note that this is *after* my stuff has been executed and is no longer on the stack. Here is the stack: o Starting program: /usr/local/httpd/bin/httpd -X Program received signal SIGSEGV, Segmentation fault. 0x80af753 in zend_hash_add_or_update (ht=0x81ab420, arKey=0x81ab4d8 "burgerking1", nKeyLength=12, pData=0xbfffe3a4, nDataSize=4, pDest=0x0, flag=1) at zend_hash.c:136 136 if ((p->h == h) && (p->nKeyLength == nKeyLength)) { (gdb) where #0 0x80af753 in zend_hash_add_or_update (ht=0x81ab420, arKey=0x81ab4d8 "burgerking1", nKeyLength=12, pData=0xbfffe3a4, nDataSize=4, pDest=0x0, flag=1) at zend_hash.c:136 #1 0x80b0a7d in zend_hash_copy (target=0x81ab420, source=0x81ab270, pCopyConstructor=0x80ad784 <zval_add_ref>, tmp=0xbfffe3a4, size=4) at zend_hash.c:833 #2 0x80ad896 in zval_copy_ctor (zvalue=0x81b9ae8) at zend_variables.c:142 #3 0x80b6572 in execute (op_array=0x81a2408) at zend_execute.c:1554 #4 0x80b621f in execute (op_array=0x81a2408) at zend_execute.c:1448 #5 0x80b621f in execute (op_array=0x81a1ac8) at zend_execute.c:1448 #6 0x80b700c in execute (op_array=0x819c3e0) at zend_execute.c:1835 #7 0x80b700c in execute (op_array=0x819afd0) at zend_execute.c:1835 #8 0x80b700c in execute (op_array=0x81998f8) at zend_execute.c:1835 #9 0x8078760 in php_execute_script (primary_file=0xbffff8c0) at main.c:1175 #10 0x80787d9 in apache_php_module_main (r=0x818f294, filename=0x81906f0 "/usr/www/index.html", fd=21, display_source_mode=0) at main.c:1218 #11 0x8077020 in send_php () #12 0x8077068 in send_parsed_php () #13 0x80bc523 in ap_invoke_handler () #14 0x80cf819 in process_request_internal () #15 0x80cfc38 in ap_internal_redirect () #16 0x807083d in handle_dir () #17 0x80bc523 in ap_invoke_handler () #18 0x80cf819 in process_request_internal () #19 0x80cf87c in ap_process_request () #20 0x80c723e in child_main () #21 0x80c73cc in make_child () #22 0x80c7529 in startup_children () ---Type <return> to continue, or q <return> to quit--- #23 0x80c7b56 in standalone_main () #24 0x80c82d3 in main () #25 0x400fbcb3 in __libc_start_main (main=0x80c7f9c <main>, argc=2, argv=0xbffffaf4, init=0x805bb60 <_init>, fini=0x810100c <_fini>, rtld_fini=0x4000a350 <_dl_fini>, stack_end=0xbffffaec) at ../sysdeps/generic/libc-start.c:78 (gdb) * Even when no crashes occur (IE, I choose a key that doesn't cause a crash, or use indexes instead), it sometimes "loses" the sub-array. By this, I mean that if I do a list($key, $val) = each($my_array), then $key will have a value, and $val will not. I have a recursive php function that walks the tree and prints all the keys and values, and one time I will get this output: o stuff => Array burgerking => 0 => BAR 1 => 10 2 => 3.45 0 => THAT and the next I will get: o stuff => Array burgerking => Array 0 => lettuce, pickles, onion, tomatoes 0 => BAR 1 => 10 2 => 3.45 0 => THAT Running the same tree-walking function on a nested array created via the php language works every single time, no exceptions. * I've also tried some of the other macros, eg zend_hash_update_ptr(), with the same result. I've checked my code very closely for memory errors, etc. I do not believe there to be any. In fact, I created the following very simple test case which exhibits the same random behavior: int i; pval* array = return_value; pval* array2; array_init(array); for (i=0; i < 15; i++) { array2 = emalloc(sizeof(pval)); array_init(array2); add_long(array, "depth", i); add_string(array2, "hi", "there", 1); zend_hash_update(array, "sub_array", strlen("sub_array")+1, (void *) &array2, sizeof(pval *), NULL); array = array2; } return;

« previous php.version4 (#5496) next »