0

我有一个这样的 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

但这在 valgrind 中的 New() 上显示为内存泄漏,如果我在循环中运行它,常驻内存将继续增长。

如果我也使用这个,我也会得到同样的结果:

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 进行编译时,会收到以下警告/错误。

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 中分配的字符串的返回?有没有办法使用 RETVAL 返回字符串并释放内存?我很感激任何帮助。

4

1 回答 1

1

在其他问题[1]中,您的第一个片段使用 分配内存New,但从不释放它。

除其他问题外,您的第二个片段使用 分配内存strdup,但从不释放它。

您的第三个片段的根本问题是您声称 XS 函数返回一个值,但它没有。该值将被分配给RETVAL,它是为此目的而自动创建的。如果您正确指定不返回任何内容,则不会创建该变量。

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.


  1. 其中之一是使用New. 你不应该使用New. 很久以前就New被弃用了。只要我记得,甚至都没有出现在文档中。NewxNew
于 2015-07-31T19:20:55.653 回答