在php扩展中分配内存

时间:2013-01-10 16:24:29

标签: php c pointers php-extension

我对C中的指针不太好。

我的PHP扩展中的内存分配有问题。我正在尝试调用一个返回浮点数组的函数。

我用C编写了一个小测试脚本,它可以工作。

基本上就是,

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");
 }

full code

此处我没有mallocfree任何内容。 (至少我不这么认为。在这段代码和函数的fortran版本中,我需要首先allocate() fld。)

然而,在我的PHP扩展中,相同的代码返回一个seg错误。

在调用emalloc之前我efreemalloc(或只是freec_fstluk)fld时,它可以正常工作,但我得到了大量的内存错误

[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)

我打赌我在这里错过了一些简单的事情......

总而言之,在独立的C程序中,东西在没有任何分配的情况下工作。在PHP扩展中,它在我分配空间时起作用,但在抛出内存错误时,当我不分配空间时,它就会出错。

帮助?谢谢!

1 个答案:

答案 0 :(得分:1)

根据此documentc_fstluk(buffer, key, &ni, &nj, &nk)将数据读入缓冲区,因此必须分配缓冲区( fld )。

在C版本中,如果 fld 未分配通常不起作用。但是根据你的系统等......或者运气不错,fld *指针可能指向一个没有写保护的随机空间(工作但当然这非常危险)。

因此扩展还要分配内存(永久或PHP请求 - 生命只取决于你的ext),然后释放它 - 在你的情况下它是一个临时分配,并且必须在离开* php_function之前释放*

我在您提供的代码中看到了什么,而注释掉了

  • emalloc执行分配
  • 然后你强制模块返回0,因为你想测试这个部分(而不是PHP vars创建等......)
  • 然后efree fld
  • 因此 fld 未释放并造成内存泄漏

所以这可能是一个简单的错误,efree应该在函数返回之前移动。

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);

根据评论进行修改

  • (float *)分配已更改为(float)
  • 所有迭代都需要
  • ALLOC_INIT_ZVAL(arow)(来源底部)