gSoap有效地创建存根以帮助进行内存管理等。其中之一 命令是soap_malloc,但似乎没有相应的soap_realloc。 在开始编写自己的push和pop方法之前,我只想确保自己没有遗漏任何明显的东西。
//example.h generated with wsdl2h
struct ns1___Customer
{
int __sizeProduct;
ns1__Product *Product;
int customerid;
}
struct ns1__Product
{
int productid;
}
我当前正在使用soap_malloc,然后重新分配以动态增长数组。
//I could use soap_new_ns1__Product(&soap,XXX) and allocate mem for XXX
//number of ns1__Product structures but this is wasteful and doesn't solve
//anything
struct ns1__Customter cust;
soap_default_ns1__Product(soap, &cust);
struct ns1__Product *prod_array = NULL;
//allocate mem for 1 product
prod_array = soap_new_ns1__Product(soap,1) ;
soap_default_ns1__Product(soap, &prod_array[0]);
prod_array[0].productid=111;
//Need to add product therefore need to realloc mem.
//IS THIS THE BEST WAY IN gsoap?
prod_array = realloc( prod_array, 2 * sizeof(struct ns1__Product)) ;
soap_default_ns1__Product(soap, &emp_array[1]);
prod_array[1].product=222;
//assigning array ptr to Customer
cust.Product=prod_array;
// Remember to adjust sizeProduct
cust.__sizeProduct=2;
这似乎是错误且笨拙的,gsoap是否建议一种更好的方法?我在文档中或通过在线搜索找不到清晰的示例。
答案 0 :(得分:1)
在我开始编写自己的push和pop方法之前,我只是想确保自己没有遗漏任何明显的东西。
我怀疑您缺少soap_malloc()
分配的内存至少在某些情况下会自动释放的。因此,使用realloc()
来调整分配的内存大小很麻烦。这样的重新分配很有可能会成功,但是当gSOAP的自动释放尝试插入soap_end()
时,您至少最终会陷入麻烦。
另一方面,我认为您不会忽略任何重新分配功能。 The docs确实似乎没有描述任何东西。您始终可以实现自己的重新分配包装器,该包装器使用soap_malloc()
分配新的内存,复制原始空间的内容(您需要某种方式知道其大小),然后使用soap_dealloc()
释放原始空间。
底线似乎是soap_malloc()
并非旨在用作通用分配器,它并不是特别适合您的用例。它的主要目标似乎是内部的,目的是使库用户无需手动释放库分配的临时对象。我将其公开给图书馆用户以供他们直接使用,目的是为了方便。
如果您希望能够重新分配块,那么我建议您首先通过常规malloc()
获得它们。如果您要混合malloc()
个数据和soap_malloc()
个数据,则需要仔细阅读文档,但这是可能的。或者,考虑不需要重新分配的方法,例如将数据存储在链接列表中,而不是动态数组中。
答案 1 :(得分:0)
您在那里所做的确实是错误的。使用soap_new_T()
(在您的情况下,T
是ns1__Product
)之后,soap
上下文现在通过内部保持ns1__Product*
指针来管理该内存。稍后,当您调用soap_destroy()
释放由soap_new_T()
上下文管理的所有soap
分配的对象时,该上下文将尝试释放自您调用以来不再指向有效内存的指针realloc()
。
就像John Bollinger pointed out一样,gSOAP中没有内置的方法来做类似于realloc
的事情。相反,您只需要手动进行重新分配,例如:
// allocate memory for 1 product (as you already do above)
prod_array = soap_new_ns1__Product(soap, 1);
// ... do some stuff, realize you need to "realloc" to add another product ...
// allocate a new array, managed by the soap context
struct ns1__Product* new_array = soap_new_ns1__Product(soap, 2);
// copy the old array into the new one (assuming old_size is however many elements are in prod_array)
for(std::size_t i = 0; i < old_size; ++i)
{
new_array[i] = prod_array[i];
}
// tell the soap context to destroy the old array
soap_dealloc(soap, prod_array);
在旁边:
似乎应该可以使用std::vector<ns1__Product>
而不是数组,这将以更好的方式解决您的问题,但是该问题已经被here要求无效。不幸的是,我目前不知道答案。