【问题标题】:Memory leak in php extension wrapped with swig用 swig 包装的 php 扩展中的内存泄漏
【发布时间】:2012-03-30 08:56:59
【问题描述】:

我在一个用 swig 包装的 PHP 扩展中存在内存泄漏。

考虑以下函数:

ZEND_NAMED_FUNCTION(_wrap_ArrayBase_get) {
  ArrayBase *arg1 = (ArrayBase *) 0 ;
  long arg2 ;
  zval **args[2];
  zval *result = 0 ;

  SWIG_ResetError();
  if(ZEND_NUM_ARGS() != 2 || zend_get_parameters_array_ex(2, args) != SUCCESS) {
    WRONG_PARAM_COUNT;
  }

  {
    if(SWIG_ConvertPtr(*args[0], (void **) &arg1, SWIGTYPE_p_ArrayBase, 0) < 0) {
      SWIG_PHP_Error(E_ERROR, "");
    }
  }

  if(!arg1) SWIG_PHP_Error(E_ERROR, "this pointer is NULL");

  /*@SWIG:/usr/local/share/swig/2.0.2/php/utils.i,7,CONVERT_INT_IN@*/
  convert_to_long_ex(args[1]);
  arg2 = (long) Z_LVAL_PP(args[1]);

  {
    try {
      result = (zval *)((ArrayBase const *)arg1)->get(arg2);
    } catch (PHPIteratorException& phpExcep ){
      //nothing to do, exception already created...  
    }
  {
    if ( result != NULL ){
      ZVAL_ZVAL(return_value,result,0,0);
    }
  }
  return;
fail:
  SWIG_ZEND_ERROR_NORETURN(SWIG_ErrorCode(),"%s",SWIG_ErrorMsg());
}

电话:

result = (zval *)((ArrayBase const *)arg1)->get(arg2);

初始化并设置 zval 但这个内存永远不会被释放。由于原始类型,zval 的初始化方式在 ArrayBase 的子类之间可能有所不同。因此,例如对于 long 类型,getter 将类似于:

zval* return_value; ALLOC_ZVAL(return_value); ZVAL_LONG(return_value, l);return return_value;

我怎样才能释放这个内存?是否有需要调用的zend 宏? 这是一个可能已在较新版本中解决的痛饮问题吗? 我正在使用 SWIG 版本 2.0.2。

【问题讨论】:

  • 由于某种原因,包装函数的一部分未在 html 中正确显示。查看页面源代码以查看对 getter 函数的调用。

标签: php memory swig memory-leaks


【解决方案1】:

我通过修复 swig 中的 zval 类型映射函数设法解决了这个问题。我在输入 zval 上调用 FREE_ZVAL 函数。

//为 zval* 键入映射 - 将它们直接传入和传出...

%typemap(out) zval*
{
    if ( $1 != NULL ){
        ZVAL_ZVAL(return_value,$1,0,0);
        FREE_ZVAL($1);
    }
} 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-10
    • 2012-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-30
    • 2019-07-16
    • 1970-01-01
    相关资源
    最近更新 更多