字符串的 Perl XS 内存处理
Perl XS Memory Handling of Strings
我有一个这样的 XSUB:
char *
string4()
CODE:
char *str = strdup("Hello World4");
int len = strlen(str) + 1;
New(0, RETVAL, len, char);
Copy(str, RETVAL, len, char);
free(str);
OUTPUT:
RETVAL
但这显示为内存泄漏,在 New() 上,在 valgrind 中,如果我 运行 它在一个循环中,驻留内存将继续增长。
如果我也用这个,我会得到同样的结果:
char *
string2()
CODE:
char *str = strdup("Hello World2");
RETVAL = str;
OUTPUT:
RETVAL
我可以通过以下方式防止泄漏和增加内存大小:
char *
string3()
PPCODE:
char *str = strdup("Hello World3");
XPUSHs(sv_2mortal(newSVpv(str, 0)));
free(str);
但是这个解决方案的问题是当我用 -Werror 编译时我得到以下 warnings/errors.
test.c: In function ‘XS_test_string3’:
/usr/lib/x86_64-linux-gnu/perl/5.20/CORE/XSUB.h:175:28: error: unused variable ‘targ’ [-Werror=unused-variable]
#define dXSTARG SV * const targ = ((PL_op->op_private & OPpENTERSUB_HASTARG) \
^
test.c:270:2: note: in expansion of macro ‘dXSTARG’
dXSTARG;
^
test.c:269:9: error: unused variable ‘RETVAL’ [-Werror=unused-variable]
char * RETVAL;
c 文件使用未使用的 RETVAL 构建:
XS_EUPXS(XS_test_string3); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_test_string3)
{
dVAR; dXSARGS;
if (items != 0)
croak_xs_usage(cv, "");
PERL_UNUSED_VAR(ax); /* -Wall */
SP -= items;
{
char * RETVAL;
dXSTARG;
#line 61 "test.xs"
char *str = strdup("Hello World3");
XPUSHs(sv_2mortal(newSVpv(str, 0)));
free(str);
#line 276 "test.c"
PUTBACK;
return;
}
}
那么有没有更好的方法来处理 XS 中分配的字符串的 returning?有没有办法使用 RETVAL return 字符串并释放内存?感谢您的帮助。
除其他问题外[1],您的第一个片段使用 New
分配内存,但从未解除分配。
除其他问题外,您的第二个代码段使用 strdup
分配内存,但从未解除分配。
您的第三个代码段的潜在问题是您声称 XS 函数 return 是一个值,但它不是。该值将被分配给 RETVAL
,它是为此目的自动创建的。如果您正确指定您没有 return 任何东西,则不会创建该变量。
void
string3()
PREINIT:
char *str;
PPCODE:
str = strdup("Hello World3");
XPUSHs(sv_2mortal(newSVpv(str, 0)));
free(str);
或者只是
void
string3()
PPCODE:
XPUSHs(sv_2mortal(newSVpv("Hello World3", 0)));
请注意,我将您的声明移出了 PPCODE
。在 C 中,声明不能出现在非声明之后,PPCODE
中的代码可以出现在非声明之后(取决于用于构建 Perl 的选项)。声明属于 PREINIT
。您还可以在 PPCODE
.
中的代码周围使用卷曲
- 其中之一是使用
New
。你不应该使用 New
。 New
很久以前就被弃用了,取而代之的是 Newx
。 New
从我记事起,我什至都没有出现在文档中。
我有一个这样的 XSUB:
char *
string4()
CODE:
char *str = strdup("Hello World4");
int len = strlen(str) + 1;
New(0, RETVAL, len, char);
Copy(str, RETVAL, len, char);
free(str);
OUTPUT:
RETVAL
但这显示为内存泄漏,在 New() 上,在 valgrind 中,如果我 运行 它在一个循环中,驻留内存将继续增长。
如果我也用这个,我会得到同样的结果:
char *
string2()
CODE:
char *str = strdup("Hello World2");
RETVAL = str;
OUTPUT:
RETVAL
我可以通过以下方式防止泄漏和增加内存大小:
char *
string3()
PPCODE:
char *str = strdup("Hello World3");
XPUSHs(sv_2mortal(newSVpv(str, 0)));
free(str);
但是这个解决方案的问题是当我用 -Werror 编译时我得到以下 warnings/errors.
test.c: In function ‘XS_test_string3’:
/usr/lib/x86_64-linux-gnu/perl/5.20/CORE/XSUB.h:175:28: error: unused variable ‘targ’ [-Werror=unused-variable]
#define dXSTARG SV * const targ = ((PL_op->op_private & OPpENTERSUB_HASTARG) \
^
test.c:270:2: note: in expansion of macro ‘dXSTARG’
dXSTARG;
^
test.c:269:9: error: unused variable ‘RETVAL’ [-Werror=unused-variable]
char * RETVAL;
c 文件使用未使用的 RETVAL 构建:
XS_EUPXS(XS_test_string3); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_test_string3)
{
dVAR; dXSARGS;
if (items != 0)
croak_xs_usage(cv, "");
PERL_UNUSED_VAR(ax); /* -Wall */
SP -= items;
{
char * RETVAL;
dXSTARG;
#line 61 "test.xs"
char *str = strdup("Hello World3");
XPUSHs(sv_2mortal(newSVpv(str, 0)));
free(str);
#line 276 "test.c"
PUTBACK;
return;
}
}
那么有没有更好的方法来处理 XS 中分配的字符串的 returning?有没有办法使用 RETVAL return 字符串并释放内存?感谢您的帮助。
除其他问题外[1],您的第一个片段使用 New
分配内存,但从未解除分配。
除其他问题外,您的第二个代码段使用 strdup
分配内存,但从未解除分配。
您的第三个代码段的潜在问题是您声称 XS 函数 return 是一个值,但它不是。该值将被分配给 RETVAL
,它是为此目的自动创建的。如果您正确指定您没有 return 任何东西,则不会创建该变量。
void
string3()
PREINIT:
char *str;
PPCODE:
str = strdup("Hello World3");
XPUSHs(sv_2mortal(newSVpv(str, 0)));
free(str);
或者只是
void
string3()
PPCODE:
XPUSHs(sv_2mortal(newSVpv("Hello World3", 0)));
请注意,我将您的声明移出了 PPCODE
。在 C 中,声明不能出现在非声明之后,PPCODE
中的代码可以出现在非声明之后(取决于用于构建 Perl 的选项)。声明属于 PREINIT
。您还可以在 PPCODE
.
- 其中之一是使用
New
。你不应该使用New
。New
很久以前就被弃用了,取而代之的是Newx
。New
从我记事起,我什至都没有出现在文档中。