Как правильно использовать и бесплатно asn1c SEQUENCE_OF? - PullRequest
1 голос
/ 07 мая 2019

Я использую библиотеку asn1c для многих проектов, но я так и не нашел, как использовать бесплатный член SEQUENCE_OF. Из-за этого я всегда устанавливаю nullptr, и когда я использую Valgrind, я вижу (конечно), что мои члены списков не освобождаются при использовании ASN_STRUCT_FREE для элемента, содержащего список.

Итак, мой вопрос, как я могу использовать этот бесплатный член?

Вот простой пример того, как я использую свои списки с asn1c.

ListItem_t *li = nullptr;
StructWList_t swl;

swl.list.count = 0;
swl.list.size = 0;
swl.list.free = nullptr; // How can I feed it properly?
swl.list.array = reinterpret_cast<ListItem_t**>(calloc(1, sizeof *swl.list.array));

for(int i = 0 ; i < 5 ; i++)
{
    li = reinterpret_cast<ListItem_t*>(calloc(1, sizeof *li));
    *li = i;
    // Valgrind says that the calloc below is definitly lost
    swl.list.array[i] = reinterpret_cast<ListItem_t*>(calloc(1, sizeof *swl.list.array[i]));
    ASN_SEQUENCE_ADD(&swl, li);
}
...
ASN_STRUCT_FREE(ASN_DEF_StructWList, &swl);

Кто-нибудь знает, как правильно его кормить?

EDIT

Моя версия asn1c - это v0.9.29 из репозитория git в AUR (на Archlinux).

Вышеприведенный ASN.1 выглядит следующим образом:

Example 
DEFINITIONS AUTOMATIC TAGS ::= 
BEGIN 

StructWList ::= SEQUENCE OF ListItem 
ListItem ::= INTEGER 
END

Заранее спасибо,

Emilien

1 Ответ

0 голосов
/ 07 мая 2019
// Valgrind says that the calloc below is definitly lost
swl.list.array[i] = reinterpret_cast<ListItem_t*>(calloc(1, sizeof *swl.list.array[i]));
ASN_SEQUENCE_ADD(&swl, li);

ASN_SEQUENCE_ADD заменит указатель, который вы сохранили в предыдущей строке.Вы должны либо сохранить его вручную, как в первой строке, либо вызвать ASN_SEQUENCE_ADD, но не оба.

Также вам следует полностью инициализировать swl, так как он содержит больше членов (_asn_ctx) и использовать ASN_STRUCT_FREE_CONTENTS_ONLY в качествеswl размещен в стеке и не может быть освобожден.

--- main.cpp.orig   2019-05-07 20:49:25.880336931 +0300
+++ main.cpp    2019-05-07 20:59:10.192431926 +0300
@@ -3,7 +3,7 @@
 int main()
 {
    ListItem_t *li = nullptr;
-   StructWList_t swl;
+   StructWList_t swl = {0};

    swl.list.count = 0;
    swl.list.size = 0;
@@ -15,8 +15,8 @@
        li = reinterpret_cast<ListItem_t*>(calloc(1, sizeof *li));
        *li = i;
        // Valgrind says that the calloc below is definitly lost
-       swl.list.array[i] = reinterpret_cast<ListItem_t*>(calloc(1, sizeof *swl.list.array[i]));
+       //swl.list.array[i] = reinterpret_cast<ListItem_t*>(calloc(1, sizeof *swl.list.array[i]));
        ASN_SEQUENCE_ADD(&swl, li);
    }
-   ASN_STRUCT_FREE(ASN_DEF_StructWList, &swl);
+   ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_StructWList, &swl);
 }

Скомпилировать с g++ -Wall -I. -ggdb -O0 -o test main.cpp libasncodec.a

valgrind --tool=memcheck ./test 
==29555== Memcheck, a memory error detector
==29555== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==29555== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==29555== Command: ./test
==29555== 
==29555== 
==29555== HEAP SUMMARY:
==29555==     in use at exit: 0 bytes in 0 blocks
==29555==   total heap usage: 9 allocs, 9 frees, 72,848 bytes allocated
==29555== 
==29555== All heap blocks were freed -- no leaks are possible
==29555== 
==29555== For counts of detected and suppressed errors, rerun with: -v
==29555== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
...