469,081 Members | 1,668 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,081 developers. It's quick & easy.

complex struct access question.

Okay I've been spending lots of time on this and it's giving me a migraine so I go humble and ask the guru's here.

I have several structs

Expand|Select|Wrap|Line Numbers
  1. typedef struct vert
  2. {
  3. int x,y,z;
  4. struct vert * next;
  5. struct vert * prev;
  6. } vertex_type;
  7.  
  8. typedef struct poly
  9. {
  10. int x,y,z;
  11. struct poly * next;
  12. struct poly * prev;
  13. } polygon_type;
  14.  
  15. //and finally.
  16. typedef struct object
  17. {
  18. char name=[20];
  19. struct vert *vertex;
  20. struct poly *polygon;
  21.  
  22. struct object * next;
  23. struct object * prev;
  24. } obj_type
  25.  
  26.  
And I initilize as such.

Expand|Select|Wrap|Line Numbers
  1.  
  2. obj_type object1={NULL};
  3. obj_type *firstobj;
  4.  
  5.  
Once my member functions are initilized and filled and the vertex pointers are filled and linked (which at this point I think is happening *fingers crossed* but am probably wrong given my problem below. )

I try and retrieve some data via, some function which takes the first object as a pointer and winds the polygon pointer to the end of the polygon list.

Expand|Select|Wrap|Line Numbers
  1. func(obj_type *current)
  2. {
  3. polygon_type *tmp;
  4. while((current->polygon->next) != NULL)
  5.     {
  6.                            tmp=current->polygon;
  7.                            current->polygon=tmp->next;
  8. }
  9.  
  10. }
  11.  
Why does it crash with a segmentation fault when it first tries to process the while statement? Am I accessing the variable incorrectly? I have tried using
Expand|Select|Wrap|Line Numbers
  1. current->polygon.next
  2.  
but my compiler says that is not defined.


Or maybe my error is in the code for creating new objects vertex's or polygons, or perhaps in the code that free them at the end.

Expand|Select|Wrap|Line Numbers
  1.  
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include "main.h"
  5.  
  6. int addobj(obj_type *last) {
  7.  
  8.     obj_type *tmp=NULL;
  9.     while(last->next!=NULL)
  10.     {
  11.                            tmp=last;
  12.     last=tmp->next;
  13. }
  14.     tmp=(obj_type*) malloc(sizeof(obj_type));
  15.     tmp->prev = last;
  16.     tmp->next = NULL;
  17.     last->next = tmp;
  18.     last=tmp;
  19.     printf("Next obj node Created.%r");
  20.     return 1;
  21.   }
  22.  
  23.   int freeobjlist(obj_type *current) {
  24.     obj_type *tmp;
  25.     while(current->next!=NULL)
  26.     {
  27.                            tmp=current;
  28.                            current=tmp->next;
  29.  
  30.                            }
  31.     while(current->prev!=NULL)
  32.     {
  33.  
  34.                            freepolygons(current);
  35.                            freeverts(current);
  36.                            freetextcoords(current);
  37.  
  38.                            tmp=current->prev;
  39.                            free(current);
  40.                            current=tmp;
  41.     printf("obj removed.%r");
  42.                            }
  43.  
  44.  
  45.  
  46.  
  47.  
  48.   return 1;
  49.  
  50.   }
  51.  
  52.   int addvertex(obj_type *current)
  53.   {
  54.  
  55.           vertex_type *tmp;
  56.     if(current->vertex==NULL)
  57.     {         
  58.               tmp=(vertex_type*)malloc(sizeof(vertex_type));
  59.                            current->vertex=tmp;
  60.                            current->vertex->prev=NULL;
  61.                            current->vertex->next=NULL;
  62.                            printf("First vertext created.%r");
  63.                            return 1;
  64.                            }
  65.     else
  66.     {
  67.       while(current->vertex->next!=NULL)
  68.       {
  69.                              tmp=current->vertex->next;
  70.                              current->vertex=tmp;
  71.                        }
  72.       tmp=(vertex_type*)malloc(sizeof(vertex_type));
  73.       current->vertex->next=tmp;
  74.       tmp->prev=current->vertex;
  75.       tmp->next=NULL;
  76.       current->vertex=tmp;
  77.       printf("Additional Vertex added.");
  78.       return 1;
  79.  
  80.  
  81.  
  82.  
  83.         }
  84.  
  85.   return 0;
  86.  
  87.       }
  88.  
  89.  
  90.  
  91. int addpolygon(obj_type *current)
  92.   {
  93.           polygon_type *tmp;
  94.     if(current->polygon==NULL)
  95.     {         
  96.               tmp=(polygon_type*)malloc(sizeof(polygon_type));
  97.                            current->polygon=tmp;
  98.                            current->polygon->prev=NULL;
  99.                            current->polygon->next=NULL;
  100.                            printf("First polygon created.%r");
  101.                            return 1;
  102.                            }
  103.     else
  104.     {
  105.       while(current->polygon->next!=NULL)
  106.       {
  107.                              tmp=current->polygon->next;
  108.                              current->polygon=tmp;
  109.                        }
  110.       tmp=(polygon_type*)malloc(sizeof(polygon_type));
  111.       current->polygon->next=tmp;
  112.       tmp->prev=current->polygon;
  113.       tmp->next=NULL;
  114.       current->polygon=tmp;
  115.       printf("Additional Vertex added.");
  116.       return 1;
  117.  
  118.  
  119.  
  120.  
  121.         }
  122.  
  123.   return 0;
  124.  
  125.       }
  126.  
  127.   int addtextcoord(obj_type *current)
  128.   {
  129.           textcoord_type *tmp;
  130.     if(current->textcoord==NULL)
  131.     {         
  132.               tmp=(textcoord_type*)malloc(sizeof(textcoord_type));
  133.                            current->textcoord=tmp;
  134.                            current->textcoord->prev=NULL;
  135.                            current->textcoord->next=NULL;
  136.                            printf("First textcoord created.%r");
  137.                            return 1;
  138.                            }
  139.     else
  140.     {
  141.       while(current->textcoord->next!=NULL)
  142.       {
  143.                              tmp=current->textcoord->next;
  144.                              current->textcoord=tmp;
  145.                        }
  146.       tmp=(textcoord_type*)malloc(sizeof(textcoord_type));
  147.       current->textcoord->next=tmp;
  148.       tmp->prev=current->textcoord;
  149.       tmp->next=NULL;
  150.       current->textcoord=tmp;
  151.       printf("Additional textcoord added.");
  152.       return 1;
  153.  
  154.  
  155.  
  156.  
  157.         }
  158.  
  159.   return 0;
  160.  
  161.       }
  162.  
  163. int freeverts(obj_type *current) {
  164.     vertex_type *tmp;
  165.     while(current->vertex->next!=NULL)
  166.     {
  167.                            tmp=current->vertex;
  168.                            current->vertex=tmp->next;
  169.  
  170.                            }
  171.     while(current->vertex->prev!=NULL)
  172.     {
  173.                            tmp=current->vertex->prev;
  174.                            free(current->vertex);
  175.                            current->vertex=tmp;
  176.     printf("vertex removed.%r");
  177.                            }
  178.     if(current->vertex!=NULL)
  179.     {
  180.               free(current->vertex);
  181.               current->vertex=NULL;
  182.                           }
  183.     printf("Master vertex cleared.%r");
  184.  
  185.  
  186.  
  187.  
  188.   return 1;
  189.  
  190.   }      
  191.  
  192. int freepolygons(obj_type *current) {
  193.     polygon_type *tmp;
  194.  
  195.  
  196.     while((current->polygon->next) != NULL)
  197.     {
  198.                            tmp=current->polygon;
  199.                            current->polygon=tmp->next;
  200.                            printf("polygon wound to end.");
  201.                            fflush(stdout);
  202.                            }
  203.     while(current->polygon->prev!=NULL)
  204.     {
  205.                            printf("Polygon deletion initiated.");
  206.                            fflush(stdout);
  207.                            tmp=current->polygon->prev;
  208.                            free(current->polygon);
  209.                            current->polygon=tmp;
  210.     printf("polygon removed.%r");
  211.                            }
  212.     if(current->polygon!=NULL)
  213.     {
  214.               free(current->polygon);
  215.               current->polygon=NULL;
  216.                           }
  217.     printf("Master polygon cleared.%r");
  218.  
  219.  
  220.  
  221.  
  222.   return 1;
  223.  
  224.   }
  225.  
  226. int freetextcoords(obj_type *current) {
  227.     textcoord_type *tmp;
  228.     while(current->textcoord->next!=NULL)
  229.     {
  230.                            tmp=current->textcoord;
  231.                            current->textcoord=tmp->next;
  232.  
  233.                            }
  234.     while(current->textcoord->prev!=NULL)
  235.     {
  236.                            tmp=current->textcoord->prev;
  237.                            free(current->textcoord);
  238.                            current->textcoord=tmp;
  239.     printf("textcoord removed.%r");
  240.                            }
  241.     if(current->textcoord!=NULL)
  242.     {
  243.               free(current->textcoord);
  244.               current->textcoord=NULL;
  245.                           }
  246.     printf("Master textcoord cleared.%r");
  247.  
  248.  
  249.  
  250.  
  251.   return 1;
  252.  
  253.   }  
  254.  




Any help is appreciated as I am apparently missing something in the way I am attempting access members of my structures and my brain is starting to feel a bit melty.
Oct 2 '07 #1
7 1917
weaknessforcats
9,208 Expert Mod 8TB
This code:
while((current->polygon->next) != NULL)
etc...
will crash if either current or polygon are null or otherwise contain addresses outside your process address space. As a rule, you should check pointers for null before applying the indirection operator.

Other observations are:
1) there is a main.h, which you don't show but which I suspect os loaded with global variables. There cound be problem there.
2) the overall code struture is "stream of consiousness". That is, steps are coded in a do-this-then-do-that order as the steps occurred to you.
3) no cncapsulation. There is next/prev/current pointers scattered all thought the code. Your linked lists are inextricably meshed with the application.

A properly written linked list will have 5 lines of code referring to the next/prev pointers of a node.

If you have a list of vertices or a list of polygons, where are the structs for the lists?? All you have are structs for the nodes.

This code:
while((current->polygon->next) != NULL)
etc...
will crash if either current or polygon are null or otherwise contain addresses outside your process address space. As a rule, you should check pointers for null before applying the indirection operator.

Other observations are:
1) there is a main.h, which you don't show but which I suspect os loaded with global variables. There cound be problem there.
2) the overall code struture is "stream of consiousness". That is, steps are coded in a do-this-then-do-that order as the steps occurred to you.
3) no cncapsulation. There is next/prev/current pointers scattered all thought the code. Your linked lists are inextricably meshed with the application.

A properly written linked list will have 5 lines of code referring to the next/prev pointers of a node.

If you have a list of vertices or a list of polygons, where are the structs for the lists?? All you have are structs for the nodes.

Maybe you should re-desgin your structs:
Expand|Select|Wrap|Line Numbers
  1. typedef struct vert
  2. {
  3.   int x,y,z;
  4. } vertex_type;
  5.  
  6. typedef struct poly
  7. {
  8.   int x,y,z;
  9. } polygon_type;
  10.  
  11. //and finally.
  12. typedef struct object
  13. {
  14. char name[20];
  15. LinkedList* vertex;
  16. LinkedList* polygon;
  17.  } obj_type;
  18.  
Here the linked lists have been removed from the data structs. Only the object has pointers to the linked lists
of vertices and polygons.

That means you need structs for the LinkedList and the Nodes in that list:
Expand|Select|Wrap|Line Numbers
  1. struct Node
  2. {
  3.      union
  4.      {
  5.          obj_type* thedata;
  6.          vertex_type* vertex;
  7.          polygon_type* polygon;
  8.      };
  9.      Node* next;
  10.      Node* prev;
  11. };
  12. struct LinkedList
  13. {
  14.     Node* start;
  15.     Node* end;
  16.     Node* current;
  17. };
  18.  
Here you see the Node contains only a pointer to the data. Now you can write linked list functions without
paying attention to what's in the list. Here is a possible function to create a linked list:
Expand|Select|Wrap|Line Numbers
  1. LinkedList* CreateLinkedList()
  2. {
  3.     LinkedList* temp = new LinkedList;
  4.     temp->start = 0;
  5.     temp->end = 0;
  6.     temp->current = 0;
  7.     return temp;
  8. }
  9.  
You can use this function inside another function that creates your object:
Expand|Select|Wrap|Line Numbers
  1. object* CreateObject()
  2. {
  3.        object* temp = new object;
  4.        temp->polygon = CreateLinkedList();
  5.        temp->vertex = CreateLinkedList();
  6.        temp->name[0] = '\0';
  7.        return temp;
  8. }
  9.  
Now in main(), all you do is create an object:
Expand|Select|Wrap|Line Numbers
  1. nt main()
  2. {
  3.  
  4.     object*  TheShape = CreateObject();
  5. }
  6.  
From here you write functions with object pointers that add the object name or add polygons or vertexes to the object's
linked lists.

Make some rules:
1) No reference to the LinkedList start, end, current members unless the function has a LinkedList* argument.
2) No reference to the Node next/prev members unless the function has Node* arguments.

Lastly, this style of code:
]
current->textcoord->next=tmp;
is called spaghetti code. It's a bad style since it exposes the member names of several structs.
Should you need to redesign any of the structs, this line will break. This will force a re-code of the entire
application. Further, if either current or textcoord is null, you crash.
Further, if either current or textcoord contains a bad address, you crash.
Oct 2 '07 #2
Thank you for the great reply, though I'm still not sure I understand the flow of what you are doing.

if I were to create a linked list of objects how would I access the member functions?

as such?
Expand|Select|Wrap|Line Numbers
  1. LinkedList *objects = createobject();
  2.  
  3. objects->current->vertex->x=1;
  4.  
  5. objects->current->vertex->y=2;
  6. objects->current->vertex->z=3;
  7.  
And then when I add another object later do I just
Expand|Select|Wrap|Line Numbers
  1. objects->next=new object;
  2.  
Assuming the function returns a valid memory location for a obj_type.

And to increment the list,
Expand|Select|Wrap|Line Numbers
  1.  
  2. objects->current=objects->next;
  3.  
  4.  
And what about adding a vertex to the structure.

would it then be
Expand|Select|Wrap|Line Numbers
  1. objects->current->vertex->next=new vertex;
  2. objects->current->vertex->current=next;
  3.  
Is this correct? I feel I can almost see the way your code works out in the end.
Oct 3 '07 #3
weaknessforcats
9,208 Expert Mod 8TB
if I were to create a linked list of objects how would I access the member functions?

as such?

Code: ( text )
LinkedList *objects = createobject();

objects->current->vertex->x=1;

objects->current->vertex->y=2;
objects->current->vertex->z=3;
You are still persisting in doing things in a serial manner. Please try to stop doing this.

You create a linked list and add objects to it:
Expand|Select|Wrap|Line Numbers
  1. object*  TheShape = CreateObject("ComplexShape");
  2. LinkedList theObjects = CreateLinkedList();
  3. AddtoEnd(theObjects, TheShape);
  4.  
The AddToEnd() would look like:
Expand|Select|Wrap|Line Numbers
  1. void AddToEnd(LinkedList* thelist, object* theobject)
  2. {
  3.    Node* temp = CreateNode(theobject);
  4.  
  5.    if (thelist->start== 0)
  6.    {
  7.        //list is empty
  8.        thelist->start = temp;
  9.        thelist->end = temp;
  10.        returnl;
  11.     {
  12.     InsertAfter(thelist->end, temp);
  13.  }
  14.  
Here the object is added to the end of the linked list. The InsertAfter is a Node function and it needs to know what the data in the union is to be.

The CreateNode(), creates a Node on the heap and assigns the data member to the union.
Expand|Select|Wrap|Line Numbers
  1. Node* CreateNode(object* data)
  2. {
  3.       Node* temp = new Node;
  4.       temp->thedata = data;
  5.       temp->next = 0;
  6.       temp->prev = 0;
  7.       return temp;
  8. }
  9.  
This InsertAfter(Node* first, Node* second) inserts the second Node after the first. I needs to handle the case where first->next is 0. The case where first->prev is 0. And the case case where neither are zero. The function is not concerned about the data in the Node but only about placing the second argument after the first.

You can use this function to insert a new node to the start of the list by calling it with the new node as the first argument and the start of the list as the secnd argument.

You can use this function to insert a new node to the end of the list by calling it with the new node as the second argument and the end of the list as the first argument.

You can use this function to insert a new node in thie middle of the list by calling it with the new node as the second argument and the Node to insert after as the secnd argument.

The code might be:
Expand|Select|Wrap|Line Numbers
  1. void InsertAfter(Node* first, Node* second)
  2. {
  3.         //Case 1: first->next is zero
  4.         if (!first->next)
  5.         {
  6.             //first->prev does not need to change
  7.             first->next = second;
  8.             second->prev = first;
  9.             //second->next does not need to change
  10.             return;
  11.         }
  12.         //first->next is not zero
  13.  
  14.  
  15.         second->prev = first;
  16.         second->next = first->next;
  17.  
  18.         first->next->prev  = second;
  19.         first->next = second;
  20.             //first->prev not changed
  21.  
  22. }
  23.  
If you do this correctly, the above function will be the only function in your application than mentions the next/prev pointers of a Node.

Then this:
if I were to create a linked list of objects how would I access the member functions?

as such?

Code: ( text )
LinkedList *objects = createobject();

objects->current->vertex->x=1;

objects->current->vertex->y=2;
objects->current->vertex->z=3;
Not this way. Remember the user does not know about start/end/current. You need functions here.
Expand|Select|Wrap|Line Numbers
  1. object*  TheShape = CreateObject("ComplexShape");
  2. LinkedList theObjects = CreateLinkedList();
  3. AddtoEnd(theObjects, TheShape);
  4. //the object is in the list but the pointer to it is still valid:
  5.  
  6. TheShape->AddVertextToEnd( 3,4,5);       //this is your member function
  7. TheShape->AddPolygonToEnd(5,6,7);
  8.  
So this might be OK:

Expand|Select|Wrap|Line Numbers
  1. void object::AddVertexToEnd(int x, int y, int z)
  2. {
  3.      Node* temp = CreateVertexNode(x,y,z);
  4.      AddToEnd(this->vertex, temp);   //from above
  5. }
  6.  
where:
Expand|Select|Wrap|Line Numbers
  1. Node* CreateVertextNode(int x, int y, int x)
  2. {     vert* obj = new vert(x,y,x)
  3.       temp->vertex = vert;
  4.       temp->next = 0;
  5.       temp->prev = 0;
  6.       return temp;
  7. }
  8.  
That's enough hints. You'll have me coding the whole thing.

Keep mind when you code a->b->c->d a big flag should appear with giant words: WRONG WAY.
Oct 3 '07 #4
Ok I started a separate program in order to help me more fully understand the way you organize your data. Let me know if I'm getting the gist of it or if you know a good reference I should look into (I.E. Linked Lists for the Dense).



Expand|Select|Wrap|Line Numbers
  1.  
  2. #include <cstdlib>
  3. #include <iostream>
  4.  
  5. using namespace std;
  6.  
  7.  
  8.  
  9.  
  10. struct aNode {
  11.        union {
  12.              struct aData *a;
  13.              struct bData *b;
  14.              };
  15.        aNode *next;
  16.        aNode *prev;
  17. };
  18.  
  19. struct aLinkedList {
  20.        aNode *start;
  21.         aNode *end;
  22.         aNode *current;
  23.        };
  24.  
  25. struct aData {
  26.        int x;
  27.         aLinkedList *MybList;
  28.        };
  29.  
  30. struct bData {
  31.        char *y;
  32.        };
  33.  
  34. aLinkedList *newlinkedlist();
  35. aData *Create_aData();
  36. bData *Create_bData();
  37. void connectnodetolist(aLinkedList *,aNode *);
  38. aNode* CreateNode();
  39. void listprint(aLinkedList*);       
  40. int main(int argc, char *argv[])
  41. {
  42.     //create list
  43.     aLinkedList *MyaList=newlinkedlist();
  44.  
  45.     //create node for list;
  46.     aNode *MyaData=CreateNode();
  47.     MyaData->a=Create_aData();
  48.     //connect MyaData to MyaList;
  49.     connectnodetolist(MyaList,MyaData);
  50.     //And again with bData
  51.     aNode *MybData=CreateNode();
  52.     MybData->b=Create_bData();
  53.  
  54.     //but First MybList must be initilized
  55.     MyaList->current->a->MybList=newlinkedlist();
  56.     //connect MybData to MyaList current data member MybList;
  57.     connectnodetolist(MyaList->current->a->MybList,MybData);
  58.  
  59.  
  60.     listprint(MyaList);
  61.  
  62.  
  63.  
  64.     system("PAUSE");
  65.     return EXIT_SUCCESS;
  66. }
  67.  
  68. aLinkedList *newlinkedlist()
  69. {
  70.     aLinkedList *temp=new aLinkedList;
  71.     temp->start=0;
  72.     temp->end=0;
  73.     temp->current=0;
  74.  
  75.     return temp; 
  76.      }
  77. aData *Create_aData()
  78. {
  79.      aData *node=new aData;
  80.      node->x=1;      
  81.      return node;
  82.       }
  83.  
  84. bData *Create_bData()
  85. {
  86.      bData *node=new bData;
  87.      node->y="Thisisit";      
  88.      return node;
  89.       }
  90.  
  91. void connectnodetolist(aLinkedList *mylist,aNode *mydata)
  92. {
  93.      if(mylist->start==0)
  94.      {
  95.                          mylist->start=mydata;
  96.                          mylist->end=mydata;
  97.                          mylist->current=mydata;
  98.                          return;
  99.                          }
  100.  
  101.      mylist->end->next=mydata;
  102.      mydata->prev=mylist->end;
  103.      mylist->end=mydata;
  104.      mylist->current=mydata;
  105.      return;
  106.      }
  107.  
  108.  
  109. aNode* CreateNode()
  110. {
  111.    aNode *node=new aNode;
  112.    node->next=0;
  113.    node->prev=0;
  114.    return node;
  115.      }
  116. void listprint(aLinkedList *theList)
  117. {
  118. //this next bit should probably just be a rewind to start of list function;
  119. if(theList->start==0) return;
  120. if(theList->current==0)
  121. {
  122. theList->current=theList->start;
  123.                      }
  124. aData *aTemp=theList->current->a;
  125. bData *bTemp=aTemp->MybList->current->b;                     
  126. printf("theList->current->a->x = %d \n",aTemp->x);
  127. printf("theList->current->a->MybList->b->y = %s\n",bTemp->y);
  128.  
  129.  
  130.            }     
  131.  
  132.  
Oct 6 '07 #5
weaknessforcats
9,208 Expert Mod 8TB
This code is much, much better.

//create list
aLinkedList *MyaList=newlinkedlist();

//create node for list;
aNode *MyaData=CreateNode();
MyaData->a=Create_aData();
//connect MyaData to MyaList;
connectnodetolist(MyaList,MyaData);
//And again with bData
aNode *MybData=CreateNode();
MybData->b=Create_bData();

//but First MybList must be initilized
MyaList->current->a->MybList=newlinkedlist();
//connect MybData to MyaList current data member MybList;
connectnodetolist(MyaList->current->a->MybList,MybData);
Here there is still too much exposed in main(). The user in main() should not need to know about nodes.

You create an object list:
Expand|Select|Wrap|Line Numbers
  1.  aLinkedList *MyaList=newlinkedlist();
  2.  
Then you add objects to the list:
Expand|Select|Wrap|Line Numbers
  1. aData* obj = CreateObject(245);
  2. AddToList(MyaList, obj);
  3.  
and that's all you see in main(). I made up the vaue for aData. I may have that wrong in concept but an object usually needs a value.

The CreateObject(int value) takes care of creating a new aData and initialize ALL of it'e members:
Expand|Select|Wrap|Line Numbers
  1. aData* CreateObject()
  2. {
  3.     aData* temp = new aData;
  4.     temp->MybList = newlinkedlist();
  5.     temp->x = value;
  6.     return temp;
  7. }
  8.  
It looks just like your newlinkedlist() function.

Notice all values are on the heap to avoid the compiler deleting something that goes out of scope. Using the heap here is very important.

Keep going in this direction. When it;s done right:

1) in main() there are only references to linked lists.
2) functions with only linkedlist* arguments are the only places where start, end and current are adjusted.
3) functions with only Node* arguments are the only places where the Node members are adjusted.

It's heartwarming to see someone try this out. Keep posting as necessary.
Oct 6 '07 #6
My code eventually evolved to this.

Expand|Select|Wrap|Line Numbers
  1. //linklist.h
  2.  
  3. class Node
  4. {
  5.  
  6.            private:
  7.  
  8.                 void *d;
  9.            Node* n;
  10.            Node* p;                    
  11.  
  12.            public:
  13.            void* obj() {return d;}
  14.            Node* next() {return n;}
  15.            Node* prev() {return p;}
  16.  
  17.            void next(Node *w) {n=w;}
  18.            void prev(Node *w) {p=w;}
  19.            Node(void *vp){n=0; p=0; d=vp;}
  20.            Node() {n=0; n=0; d=0;}
  21.       };
  22. struct LinkedList 
  23. {
  24.           private:
  25.           Node* start;
  26.           Node* end;
  27.           Node* current;
  28.           int index;
  29.           public:
  30.           void* element(unsigned short); //set current to node # max node # = qty;
  31.           void* obj() {return current->obj();}
  32.           unsigned short add(void *);
  33.           void rewind() {current=start;}   
  34.           void* next() {current=current->next(); return current->obj();}
  35.           void* prev() {current=current->prev(); return current->obj();}
  36.           int qty() {return index;}
  37.           LinkedList(void *vp) {add(vp);}
  38.           LinkedList() {start=0; end=0; current=0; index=0;}     
  39.       } ;
  40.  
  41. //linkedlists.cpp
  42.  
  43. unsigned short LinkedList::add(void *vPtr)
  44. {
  45.  
  46.             Node *nTemp=new Node(vPtr);
  47.  
  48.             if((index++)==0)
  49.             {
  50.             start=nTemp;
  51.             end=nTemp;
  52.             current=nTemp;
  53.             return index;  
  54.             }          
  55.             nTemp->prev(end);
  56.             end->next(nTemp);
  57.             end=nTemp;
  58.  
  59.  
  60.             return index;              
  61.  
  62.      }
  63.  
  64.  
  65. void* LinkedList::element(unsigned short x)
  66. {
  67.  
  68.  
  69.        rewind();
  70.        for(int i=0;(i<index) && (i<x);i++)  
  71.           {
  72.           current=current->next();
  73.           }
  74.           return current->obj();
  75.           }
  76.  
  77.  
I think the encapsulation routine is much better. Now I can feed it any data type and return the data very quickly casting my data to type as I go. I think anyway, haven't really tested it as it required almost a complete rewrite of the program I had started. Is this more what you had in mind when you spoke of the cessation of serialization in my code?

I'm still kinda working over the bump from c to c++, but I'm really starting to like c++.
Oct 9 '07 #7
weaknessforcats
9,208 Expert Mod 8TB
This is pretty good.

However, there is still cross-pollination between LinkedList and Node. That is, you are still using next/prev outside a Node member funciton.

This code:
unsigned short LinkedList::add(void *vPtr)
{

Node *nTemp=new Node(vPtr);

if((index++)==0)
{
start=nTemp;
end=nTemp;
current=nTemp;
return index;
}
nTemp->prev(end);
end->next(nTemp);
end=nTemp;


return index;

}
that adds a Node to the list should be:
Expand|Select|Wrap|Line Numbers
  1. void LinkedList::add(void *vPtr)
  2. {
  3.  
  4.             Node *nTemp=new Node(vPtr);
  5.  
  6.             if(start ==0)
  7.             {
  8.                start=nTemp;
  9.                end=nTemp;
  10.                current=nTemp;
  11.                return;
  12.             }          
  13.             end.InsertAfter(nTemp);             
  14.  
  15.             return index;              
  16.  
  17.      }
  18.  
Here the linked list function calls a Node function to do the add.

Node::InsertAfter() would be a member function that inserts the node in the argument after the node used on the call. Maybe:
Expand|Select|Wrap|Line Numbers
  1. void Node::InsertAfter(Node* second)
  2. {
  3.         //Case 1: this->next is zero
  4.         if (!this->next)
  5.         {
  6.             //this->prev does not need to change
  7.             this->next = second;
  8.             second->prev = this;
  9.             //second->next does not need to change
  10.             return;
  11.         }
  12.         //Case 2: this->next is not zero
  13.  
  14.  
  15.         second->prev = this;
  16.         second->next = this->next;
  17.  
  18.         this->next->prev  = second;
  19.         this->next = second;
  20.                            //this->prev not changed
  21.  
  22. }
  23.  
You can use this goodie to:
Expand|Select|Wrap|Line Numbers
  1. nTemp.InsertAfter(start);      //adds nTemp as Ist node
  2. nPos.InsertAfter(nTemp);    //adds nTemp after the node nPos in the middle
  3.                                          //of the list
  4.  
Then this member function in the LinkedList struct:
void* next() {current=current->next(); return current->obj();}
is really two member functions packed into one:
Expand|Select|Wrap|Line Numbers
  1. void Advance();
  2. void* GetData();
  3.  
Here are possible implementations:
Expand|Select|Wrap|Line Numbers
  1. void LinkedList::Advance()
  2. {
  3.    this->current = this->current->GetNext();
  4. }
  5.  
where GetNext() is a call to a Node function:
Expand|Select|Wrap|Line Numbers
  1. Node* Node::GetNext()
  2. {
  3.        return n->next;
  4. }
  5.  
And to get the value at the current position:
Expand|Select|Wrap|Line Numbers
  1. void* LinkedList::GetData()
  2. {
  3.      return this->current->GetData();  //calls Node::GetData()
  4. }
  5.  
where:
Expand|Select|Wrap|Line Numbers
  1. void* Node::GetData()
  2. {
  3.      return this->GetData();
  4. }
  5.  
As you can see your code is shaping up very nicely. All of this encapsulation stuff is just experience.
Oct 10 '07 #8

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

7 posts views Thread by seia0106 | last post: by
6 posts views Thread by mark | last post: by
5 posts views Thread by spasmous | last post: by
7 posts views Thread by Urs Wigger | last post: by
reply views Thread by Ivan | last post: by
11 posts views Thread by jacob navia | last post: by
1 post views Thread by CARIGAR | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.