Memory management 在没有内存异常的情况下,如何使用DSSetHandleSize()为集群的LabVIEW数组分配内存

Memory management 在没有内存异常的情况下,如何使用DSSetHandleSize()为集群的LabVIEW数组分配内存,memory-management,dll,labview,Memory Management,Dll,Labview,我能够可靠地使用LabVIEW字符串数组。当我尝试对集群数组执行相同的操作时,当增加句柄大小时,它总是在从DLL返回时崩溃 代码是: typedef struct { uint8_t depth; LStrHandle name; LStrHandle child; } TreeElem; typedef struct { int32_t dimSize; TreeElem Element[1]; } **TreeHdl; MSEXPOR

我能够可靠地使用LabVIEW字符串数组。当我尝试对集群数组执行相同的操作时,当增加句柄大小时,它总是在从DLL返回时崩溃

代码是:

typedef struct {
    uint8_t depth;
    LStrHandle name;
    LStrHandle child;
    } TreeElem;
typedef struct {
    int32_t dimSize;
    TreeElem Element[1];
    } **TreeHdl;

MSEXPORT void BuildTreeCtl(int32_t depth, uint32_t xmlNodePtr, TreeHdl TreeCluster)
{
    xmlNode *cur_node, *chile_node;

    for (cur_node = (xmlNode *) xmlNodePtr; cur_node; cur_node = cur_node->next) {
        
        if (cur_node->type == XML_ELEMENT_NODE) {
            DSSetHandleSize(TreeCluster, sizeof(int32) + (sizeof(TreeElem) * ((*TreeCluster)->dimSize + 1)));
            int idx = (*TreeCluster)->dimSize++;
             
            if (cur_node->name != NULL) {
                    LV_STR_NEW(((*TreeCluster)->Element)[idx].name, (char*) cur_node->name);}
            //  check for CDATA
            for (chile_node = cur_node->children; chile_node; chile_node = chile_node->next) {
                if (chile_node->type == XML_CDATA_SECTION_NODE) {
                    if (chile_node->content != NULL) {
                            LV_STR_NEW(((*TreeCluster)->Element)[idx].child, (char*) chile_node->content);
                    }
                }
            }
            BuildTreeCtl(depth + 1, (uint32_t) cur_node->children, TreeCluster);
        }
    }
}

事实证明,当增加数组大小时,
DSSetHandleSize()
(至少适用于LabVIEW 2013及更早版本)不会将新内存初始化为零。此外,它可能会使用与进入时不同的句柄分配新的内存块-它确实会将现有数据可靠地传输到新的内存分配,但新内存块中存在的任何内容都会导致LabVIEW在返回时崩溃,这肯定是因为LabVIEW使用了垃圾指针

代码应为:

MSEXPORT void BuildTreeCtl(int32_t depth, uint32_t xmlNodePtr, TreeHdl TreeCluster)
{
    xmlNode *cur_node, *chile_node;

    for (cur_node = (xmlNode *) xmlNodePtr; cur_node; cur_node = cur_node->next) {
        
        if (cur_node->type == XML_ELEMENT_NODE) {
            DSSetHandleSize(TreeCluster, sizeof(int32) + (sizeof(TreeElem) * ((*TreeCluster)->dimSize + 1)));
            int idx = (*TreeCluster)->dimSize++;


调用DSSetHSzClr而不是DSSetHandleSize。

调用DSSetHSzClr而不是DSSetHandleSize.Ouch。您可能认为会提到清除数据或引用
DSSetHSzClr()
,但它们只引用
NumericArrayResize()
。我会把它放在NI和糟糕的文档上。谢谢
            #if 0   // brute force
                (((*TreeCluster)->Element)[idx]).depth = depth;
                (((*TreeCluster)->Element)[idx]).name = NULL;
                (((*TreeCluster)->Element)[idx]).child = NULL;
            #elif 0 // generic
                uint8_t *Ptr = (uint8_t *) &(((*TreeCluster)->Element)[idx]);
                for (int j=0; j<sizeof(TreeElem); j++) {*(Ptr + j) = 0;}
            #else
                uint8_t *Ptr = (uint8_t *) &(((*TreeCluster)->Element)[idx]);
                memset(Ptr, 0, sizeof(TreeElem));       
            #endif  
            if (cur_node->name != NULL) {
                    LV_STR_NEW(((*TreeCluster)->Element)[idx].name, (char*) cur_node->name);}
            //  check for CDATA
            for (chile_node = cur_node->children; chile_node; chile_node = chile_node->next) {
                if (chile_node->type == XML_CDATA_SECTION_NODE) {
                    if (chile_node->content != NULL) {
                            LV_STR_NEW(((*TreeCluster)->Element)[idx].child, (char*) chile_node->content);
                    }
                }
            }
            BuildTreeCtl(depth + 1, (uint32_t) cur_node->children, TreeCluster);
        }
    }
}