LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

ListType of structures containing ListTypes, help.

I have some semi complex code which I will do my best to explain, I have a List containing TestNode structures, and TestNode contain a list that contains TestParameter structures.  I have included the relevant code and will continue explaining at the bottom of this post.
 

// Title:       NodeTypes.h
#ifndef __NodeTypes_H__
#define __NodeTypes_H__
#include <toolbox.h>

struct _TestNode
{
   char key[100];
   ListType ParameterList;
};
typedef struct _TestNode TestNode;
struct _TestParameter
{
   char *ParameterType;
   char *ParameterValue;
};
typedef struct _TestParameter TestParameter;
#endif  /* ndef __NodeTypes_H__ */
 
 
 
 
 
 
// Title:       Treeview.c
#include <userint.h>
#include "NodeTypes.h"
#include "GUIHandles.h"
#include "editpanel.h"
#include "Treeview.h"
 
ListType TestList()
{
   ListType static TestList = NULL;
   if (TestList == NULL)
   {
      TestList = ListCreate (sizeof(TestNode));  
   }
   return TestList;
}
void PopulateTree(void)
{
   AddTest("mytest");     
   AddTest("mytest2");
   AddParameter("mytest", "connection", "IO1_POS");
}
void AddNode(void)
{
  
}
TestNode *AddTest(char testname[100])
{
   ListType PList = ListCreate (sizeof(TestParameter));
   TestNode *temp = malloc(sizeof(TestNode));
  
   temp->ParameterList = PList;
   strcpy(temp->key,testname);
  
   ListInsertItem (TestList(), temp, END_OF_LIST);
   return temp;
}
TestParameter *AddParameter(char testname[100], char *parametertype, char *parametervalue)
{
   TestNode result;
   TestParameter *temp = malloc(sizeof(TestParameter)); 
   FindTest(testname, &result);
  
  
   temp->ParameterType = parametertype;
   temp->ParameterValue = parametervalue;
   ListInsertItem(result.ParameterList, temp, END_OF_LIST);
   return temp;
}
void FindTest(char testname[100], TestNode *result)
{
   TestNode temp;
   int count = ListNumItems (TestList());
   int x=0;
  
   for (x=1; x<=count; x++)
   {
      ListGetItem(TestList(), &temp, x);
      if (strcmp(temp.key,testname)==0)
      {
         result = &temp;
         return;
      }
   }
}
 
everything works up until FindTest is called, it successfully finds 'testname' in temp.key and assigns result to the address of temp, but upon kicking back to AddParameter, the local variable 'result' is a garbage pointer for no apparent reason, the memory address does not match the addess that was retrieved into temp.  Am I using the List "object" wrong? (grumbles about C being a stone age language and hardly appropriate for the kind of work we do for the 6.02*10^23 time this month)
0 Kudos
Message 1 of 5
(3,892 Views)
"temp" is a variable local to FindTest function: when returned to the caller the local variable is no more valid and the pointer effectively contains nothing but garbage. You could return the value of "x" instead, and perform another ListGetItem within AddParameter function: this should work.


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 2 of 5
(3,878 Views)

Alternatively, you could consider replacing your FindTest function with a single ListFindItem () function inside your TestParameter function. ListFindItem requires a compare function which in your case could be something like this:

int compareFunc (void *element1, void *element2)

/*
   Return values:

     If element1 is                      compar returns
 --------------------------------------------------------------
   less than element2                    less than zero
   equal to element2                     zero
   greater than element2                 greater than zero
*/
{
 int   ncar;
 TestNode *e1, *e2;

 e1 = (TestNode *)element1;
 e2 = (TestNode *)element2;
 //return strcmp (e1->cod, e2->cod);
 ncar = Min (strlen(e1->key), strlen (e2->key));
 return strncmp (e1->key, e2->key, ncar);
}

This function returns the position of found element inside the list, so you could use ListReplaceItem instead of appending a new item to the end of the list.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 3 of 5
(3,874 Views)
about the pointer issue: that's kinda what i thought, but since temp was already a pointer to a known bit of memory (an element of the list) and result was a COPY of said memory address and was returned by reference, wouldn't it logically follow that result would point to the same location in memory as the now defunct "temp"?
0 Kudos
Message 4 of 5
(3,852 Views)

Sorry, no; it does not follow.

The memory for the variables "temp", "count" and "x" is allocated on the heap, and becomes available to other threads in your process (and therefore liable to be trashed) immediately FindTest() returns.

Instead of:
  result = &temp;
you could do this:
  *result = temp;
which will copy the contents of "temp" to the variable "result" in the AddParameter() function.

Colin.

[Avogadro?]



Message Edited by cdk52 on 03-28-2008 09:28 AM
0 Kudos
Message 5 of 5
(3,823 Views)