gpt4 book ai didi

PHP 扩展 - RETURN_STRING

转载 作者:行者123 更新时间:2023-11-28 06:28:42 25 4
gpt4 key购买 nike

在 PHP 扩展中,这有什么区别:

PHP_METHOD(TestExtension, test)
{
MyClass *myclass;
MyClass_Object *obj = (MyClass_Object*)zend_object_store_get_object(getThis() TSRMLS_CC);
myclass = obj->myclass;
if (myclass != NULL)
{
string retval = myclass->test();
RETURN_STRING(retval.c_str(), 1);
}
RETURN_NULL();
}

还有这个:

PHP_METHOD(TestExtension, test)
{
MyClass *myclass;
MyClass_Object *obj = (MyClass_Object*)zend_object_store_get_object(getThis() TSRMLS_CC);
myclass = obj->myclass;
if (myclass != NULL)
{
RETURN_STRING(myclass->test().c_str(), 1);
}
RETURN_NULL();
}

?

两者似乎都可以工作,但是当我运行 valgrind 时:

valgrind --tool=memcheck --num-callers=30 --log-file=./php.log /usr/bin/php test.php

test.php 在哪里:

<?php
$obj = new TestExtension("testing");
echo $obj->test() . "\n";
?>

然后后者给了我一大堆错误,所有错误都是:

Address 0xe4c3e98 is 24 bytes inside a block of size 66 free'd

valgrind总结如下:

126 ==23067== HEAP SUMMARY:
127 ==23067== in use at exit: 9,031 bytes in 15 blocks
128 ==23067== total heap usage: 25,131 allocs, 25,116 frees, 4,435,757 bytes allocated
129 ==23067==
130 ==23067== LEAK SUMMARY:
131 ==23067== definitely lost: 0 bytes in 0 blocks
132 ==23067== indirectly lost: 0 bytes in 0 blocks
133 ==23067== possibly lost: 0 bytes in 0 blocks
134 ==23067== still reachable: 9,031 bytes in 15 blocks
135 ==23067== suppressed: 0 bytes in 0 blocks
136 ==23067== Rerun with --leak-check=full to see details of leaked memory
137 ==23067==
138 ==23067== For counts of detected and suppressed errors, rerun with: -v
139 ==23067== ERROR SUMMARY: 48 errors from 5 contexts (suppressed: 0 from 0)

最佳答案

虽然它没有在 RETURN_STRING 宏的文档中说明(这似乎是一个遗漏:它应该明确说明生命周期要求),但宏似乎扩展到不止一行。

比如说:

RETURN_STRING(myclass->test().c_str(), 1);

变成:

const char* arg = myclass->test().c_str();
someCode();
someMoreCode();
finalCode(arg);

arg 在最后一行无效,因为(假设它按值返回)myclass->test() 的临时结果仅在第一行。因此,myclass->test().c_str() 的结果也仅在第一行期间有效。 arg 之后立即变为悬挂指针。

您的解决方法是解决此问题的正确方法。我建议,在使用这些宏中的任何一个时,确保向它传递一个指向数据的指针,该指针至少在宏运行期间仍然存在,无论有多少语句/表达式,肯定这可能涉及。

这是我要做的:

if (myclass != NULL) {
const string& retval = myclass->test();
RETURN_STRING(retval.c_str(), 1);
}

现在,无论 myclass->test() 是什么,它都会在宏的所有扩展语句中存活下来,您不必将它复制到新的 std::string 对象。

关于PHP 扩展 - RETURN_STRING,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28065415/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com