首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在PHP扩展中,从和std::string返回值的推荐方式

在PHP扩展中,从和std::string返回值的推荐方式
EN

Stack Overflow用户
提问于 2018-05-22 18:11:46
回答 1查看 624关注 0票数 2

我们有一个简单的PHP函数,它的目的是调用一个C++自由函数std::string callLibrary(std::string)并返回它的std::string返回值。

它目前看起来是这样的:

代码语言:javascript
复制
PHP_FUNCTION(call_library)
{
    char *arg = NULL;
    size_t arg_len, len;
    if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE)
    {
        return;
    }

    // Call underlying library
    std::string callResult = callLibrary(arg);
    zend_string * result = zend_string_init(callResult.c_str(), callResult.size(), 0);
    RETURN_STR(result);
}

我们找不到一本描述zend_string_initRETURN_STR()行为的参考手册,我们所拥有的最接近的是:http://www.phpinternalsbook.com/php7/internal_types/strings/zend_strings.html

特别是,它对zend_string_init的最后一个参数进行了说明

如果传递0,则要求引擎使用Zend内存管理器进行请求绑定的堆分配。此类分配将在当前请求结束时销毁。如果你不自己做,在调试版本上,引擎会对你大喊你刚刚造成的内存泄漏。如果您传递1,您将请求我们所说的“持久”分配,即引擎将使用传统的C malloc()调用,并且不会以任何方式跟踪内存分配。

看起来我们需要0的值,但是RETURN_STR()会释放分配的内存吗?(文本有点模棱两可,但看起来破坏应该是明确的)有没有一种更常用的方法从std::string扩展函数返回这样的PHP值?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-11 05:30:59

为了回答您的问题,我将先简单介绍一下PHP内存分配,然后再讨论您的具体问题。

关于PHP内存分配

在编写PHP扩展时,您可以执行两种内存分配:

  • tracked allocations
  • persistent memory allocations

跟踪的内存分配

跟踪内存分配是一种优化,允许PHP引擎对原始内存分配有更多的控制。Zend内存管理器(ZendMM)充当标准内存分配库之上的包装器。此内存管理器允许PHP通过清理任何未在请求结束时显式释放的跟踪内存来避免内存泄漏。此外,这允许引擎设定内存限制(例如php.ini设置memory_limit)。由于这些原因,跟踪内存也称为按请求内存。

持久内存分配是由C库(例如malloc和朋友)管理的标准内存分配。同样值得注意的是,在C++中,newdelete通常分别向下调用mallocfree。在PHP中,持久性内存分配在处理请求后仍然有效,它的存在可能是为了服务于多个请求。因此,使用这些类型的分配可能会导致内存泄漏。

在PHP中,有一些宏是为执行跟踪或持久内存分配而定义的。例如,emallocefree类似于mallocfree,用于跟踪(即按请求)内存管理。宏pemallocpefree用于跟踪或持久分配,它们有一个可切换的参数。例如,pemalloc(32,1)分配32个持久字节块,而pemalloc(32,0)等效于emalloc(32)分配32个跟踪字节的块。

除了原始内存分配函数之外,PHP API还提供对由更高级别函数发起的内存分配的控制。例如,通过使用zend_string_init创建PHP7 zend_string结构,您可以通过第三个参数选择所需的内存分配类型。这在整个应用程序接口中遵循一个常见的习惯用法,0表示跟踪分配,1表示持久分配。

关于zend_string**,** zend_string_init zend_string**,的

我对PHP7并不像对PHP5那么熟悉,但是我已经继承了很多概念,我想我已经阅读了足够多的源代码来回答这个问题。当您使用RETURN_STRzend_string分配给zval时,zval将负责释放zend_string (在PHP5中,这只是一个char*,但概念是相同的)。Zend引擎希望使用跟踪的内存管理器分配大多数对象。在PHP5中,分配给zval的字符串必须是通过emalloc分配的,因为当zval被销毁时,代码总是在字符串缓冲区上调用efree。在PHP7中,似乎有an exception,因为zend_string结构可以记住使用了哪种分配类型。无论如何,最好始终使用跟踪的分配作为默认值,除非您有很好的理由这样做。因此,您当前的代码看起来不错,因为它将0作为第三个参数传递给zend_string_init

在您的代码中不应该显式地销毁zend_string,因为zval将在以后的某个时间处理该问题。此外,该过程依赖于用户空间如何在返回的zval上操作。这不是你必须担心的事情。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50465101

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档