I'm not good with pointers in C)
Having trouble with memory allocation in my PHP extension. I'm trying to call a function that returns an array of floats.
I wrote a small test script in C, and it works.
Basically it's,
float *fld;
...
ier = c_fstluk(fld, key, &ni, &nj, &nk);
...
// Read the array as a 2d field
for (i=0; i<ni; i++) {
for (j=0; j<nj; j++) {
// Values come transposed..
printf("%15.6E", *(fld+(ni*j)+i));
if (j<nj-1) printf(", ");
}
printf("\n");
}
Here I don't have to malloc
or free
anything. (at least I don't think so. In the fortran version of this code and function, I need to allocate()
fld first.)
In my PHP extension however, the same code returns a seg fault.
When I emalloc
and efree
(or just malloc
and free
) fld before calling c_fstluk
, it works, but I get tonnes of memory errors.
[Wed Jan 9 15:34:33 2013] Script: '/Users/matt/aurams/trunk/web/php/php-src/ext/fstd/fstd.php'
/Users/matt/aurams/trunk/web/php/php-src/Zend/zend_API.c(1295) : Freeing 0x10D953060 (72 bytes), script=/Users/matt/aurams/trunk/web/php/php-src/ext/fstd/fstd.php
/Users/matt/aurams/trunk/web/php/php-src/Zend/zend_hash.c(412) : Actual location (location was relayed)
Last leak repeated 779 times
[Wed Jan 9 15:34:33 2013] Script: '/Users/matt/aurams/trunk/web/php/php-src/ext/fstd/fstd.php'
/Users/matt/aurams/trunk/web/php/php-src/Zend/zend_API.c(1292) : Freeing 0x10D9531A0 (32 bytes), script=/Users/matt/aurams/trunk/web/php/php-src/ext/fstd/fstd.php
Last leak repeated 779 times
[Wed Jan 9 15:34:33 2013] Script: '/Users/matt/aurams/trunk/web/php/php-src/ext/fstd/fstd.php'
ext/fstd/fstd.c(414) : Freeing 0x10D9538D0 (72 bytes), script=/Users/matt/aurams/trunk/web/php/php-src/ext/fstd/fstd.php
/Users/matt/aurams/trunk/web/php/php-src/Zend/zend_API.c(982) : Actual location (location was relayed)
Last leak repeated 29 times
[Wed Jan 9 15:34:33 2013] Script: '/Users/matt/aurams/trunk/web/php/php-src/ext/fstd/fstd.php'
/Users/matt/aurams/trunk/web/php/php-src/Zend/zend_hash.c(450) : Freeing 0x10D954C08 (256 bytes), script=/Users/matt/aurams/trunk/web/php/php-src/ext/fstd/fstd.php
Last leak repeated 29 times
=== Total 1620 memory leaks detected ===
(Full code with emalloc
commented out, line ~398)
I bet I'm missing something simple here..
So to summarize, in stand alone C program, stuff works without any allocation. In PHP extension, it works when I allocate space, but throws memory errors, when I don't allocate space, it seg faults.
Help? Thanks!
According to this document, c_fstluk(buffer, key, &ni, &nj, &nk)
reads data into buffer, therefore the buffer (fld) has to be allocated.
In the C version, if should normally not work having fld unallocated. But depending on your system etc... or some luck, the fld *
pointer may point to a random space that is not written-protected (works but, of course, this is extremely dangerous).
Therefore the extension has also to allocate the memory (either permanent or PHP request-life only depending on your ext) and then release it - in your case it is a temporary allocation, and has to be released before leaving the *php_function*.
What I can see in the code you provided, while commented out
emalloc
does the allocation0
since you want to test this part (and not the PHP vars creation etc...)efree
fldSo it is probably a simple mistake, the efree
should be moved just before the return of the function.
fld = emalloc(ni*nj*sizeof(float*)); /* sizeof(float) INSTEAD? */
// Read the field pointed by the given key
ier = c_fstluk(fld, key, &ni, &nj, &nk);
/* ... */
php_printf("\nDone.\n");
efree(fld);
RETURN_LONG(0);
edit based on comments
(float *)
allocation changed to (float)
ALLOC_INIT_ZVAL(arow)
to be done for all iterations (source bottom)