Valhalla Legends Forums Archive | C/C++ Programming | deletion help needed

AuthorMessageTime
whitewidow
i need some help with my program cause i have done, all the coding but i cant figure out y i cant get my program to delete, and when i add a data to the program, i found out that i cant add more and than 2 items, it just overwrites the previous entered data.

this is my code.


[code]
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include <string.h>

struct node
{
node *prev, *next;
char* pszFirstName;
char* pszSurName;
char* pszCountry;
long nYear;
};

class CFileStuff
{
public:

CFileStuff()
{
mFile = 0;
mWrite = false;
}

~CFileStuff()
{
close();
}

bool open(const char* pszFileName, bool bWrite)
{
mWrite = bWrite;
mFile = fopen(pszFileName, (mWrite) ? "w+t" : "r+t");
return mFile != 0;
}

void close()
{
if (mFile)
{
if (mWrite)
fflush(mFile);
fclose(mFile);
}

mFile = 0;
}

void operator <<(const char* psz)
{
size_t len = strlen(psz);
fwrite(&len, sizeof len, 1, mFile);
fwrite(psz, sizeof(char), len, mFile);
}

void operator <<(long n)
{
fwrite(&n, sizeof(n), 1, mFile);
}

void operator >>(char*& psz)
{
size_t len;
fread(&len, sizeof len, 1, mFile);
psz = new char[len + 1];
psz[len] = 0;
fread(psz, sizeof(char), len, mFile);
}

void operator >>(long& n)
{
fread(&n, sizeof n, 1, mFile);
}

FILE* mFile;
bool mWrite;
};


int size=0;

bool createNode(node*& pHead)
{
node* pNode = new node;
memset(pNode, 0, sizeof node);

char szBuffer[255];
printf("\nENTER FIRST NAME: ");
scanf("%s",szBuffer);
pNode->pszFirstName = new char[strlen(szBuffer) + 1];
strcpy(pNode->pszFirstName, szBuffer);

printf("\nENTER LAST NAME: ");
scanf("%s",szBuffer);
pNode->pszSurName = new char[strlen(szBuffer) + 1];
strcpy(pNode->pszSurName, szBuffer);

printf("\nENTER COUNTRY: ");
scanf("%s",szBuffer);
pNode->pszCountry = new char[strlen(szBuffer) + 1];
strcpy(pNode->pszCountry, szBuffer);

printf("\nENTER YEAR: ");
scanf("%s",szBuffer);
pNode->nYear = atol(szBuffer);

if (pHead != 0)
{
printf("\nENTER POSITION: ");
scanf("%s",szBuffer);
long lPos = atol(szBuffer);

long lCnt = 0;
node* pCurPos, *pPrev;
pPrev = pCurPos = pHead;

while (lCnt < lPos && pCurPos)
{
lCnt++;
pPrev = pCurPos;
pCurPos = pCurPos->next;
}

if (lPos == 0 && lCnt == lPos)
{
pNode->next = pHead;
pHead = pNode;
}
else
{
pNode->next = pPrev->next;
pPrev->next = pNode;
}
}
else
pHead = pNode;


return true;
}



void display(node* pNode)
{
if (pNode)
{
node* pCurNode = pNode;
while (pCurNode)
{
printf("%s, %s\t\t%s\t%d\n", pCurNode->pszSurName, pCurNode->pszFirstName, pCurNode->pszCountry, pCurNode->nYear);
pCurNode = pCurNode->next;
}
}
else
printf("\nLIST EMPTY\n\n");
}

void deleteNode(node*& pHead)
{
char szBuffer[255];
printf("\nENTER POSITION: ");
scanf("%s",szBuffer);
long lPos = atol(szBuffer);

node* pNext;
if (lPos == 0)
{
pNext = pHead;
delete pHead;
pHead = pNext;
}
else
{

// while (lCnt < lPos)
}

}

void saveList(char* pszfilename, node* pHead)
{
CFileStuff f;
f.open(pszfilename, true);

long nCnt = 0;
node*p = pHead;
while (p)
{
nCnt++;
p = p->next;
}

f << nCnt;

p = pHead;
while (p)
{
f << p->pszFirstName;
f << p->pszSurName;
f << p->pszCountry;
f << p->nYear;
p = p->next;
}
}

node* loadList(char* pszfilename)
{
CFileStuff f;
if (!f.open(pszfilename, false))
return 0;

node* head = 0;
node* pCur = 0;
node* pLast = 0;

long lCnt = 0;
f >> lCnt;

long lPos = 0;
while (lPos < lCnt)
{
pCur = new node;
memset(pCur, 0, sizeof node);
f >> pCur->pszFirstName;
f >> pCur->pszSurName;
f >> pCur->pszCountry;
f >> pCur->nYear;
if (head == 0)
head = pLast = pCur;
else
pLast->next = pCur;

lPos++;
}

return head;
}

void main()
{
node* pHead = 0;
char szFilename[] = "D:\\test.txt";
int choice = 1;
pHead = loadList(szFilename);

while (choice)
{
printf("\nMENU\n");
printf("\n1 : DISPLAY");
printf("\n2 : INSERT");
printf("\n3 : DELETE");
printf("\n4 : EXIT");
printf("\n\nENTER CHOICE: ");
scanf("%d",&choice);

switch(choice)
{
case 1:
display(pHead);
break;

case 2:
createNode(pHead);
saveList(szFilename, pHead);
pHead = loadList(szFilename);
break;
case 3:
deleteNode (pHead);
saveList(szFilename, pHead);
pHead = loadList(szFilename);
// del_node();
break;

case 4:
choice = 0;
break;

default:
printf("\nINVALID CHOICE");
}
}
}
[/code]


i need some help, please help me


Edit (Yoni): Use code tags please.
May 19, 2004, 2:05 PM
Zeller
[code]
char szFilename[] = "D:\\test.txt";
[/code]

Is it possible having have 2 slashes is causing the problem? just trying to help ;D
May 19, 2004, 7:41 PM
j0k3r
I believe two slashes is used to represent the slash character in a string, as the slash character is the escape character.
May 19, 2004, 8:50 PM
iago
[quote author=j0k3r link=board=30;threadid=6875;start=0#msg60841 date=1084999838]
I believe two slashes is used to represent the slash character in a string, as the slash character is the escape character.
[/quote]

Yes, \\ is correct.
May 19, 2004, 11:23 PM
Myndfyr
[quote author=whitewidow link=board=30;threadid=6875;start=0#msg60809 date=1084975555]
i need some help with my program cause i have done, all the coding but i cant figure out y i cant get my program to delete, and when i add a data to the program, i found out that i cant add more and than 2 items, it just overwrites the previous entered data.

i need some help, please help me
[/quote]

OK, first of all, modify your original post and put the code within the [ code] and [ /code] tags (take the spaces out).

Second of all, if you want help, say what it is you're trying to do. I'm not going to take the time out of my day to attempt to ascertain (possibly incorrectly) what it is your program is supposed to delete, or even do for that matter.

I suggest you explain 1.) what the point of the program (or this particular piece of the program) is, 2.), exactly what the program is supposed to be doing but isn't, 3.) what solutions you have already tried but did not work, and 4.) what you suspect might be causing the problem.

[me=Myndfyre]sighs[/me]

Since I'm nice, I decided to look through your function declarations. It looks like you're trying to maintain a linked list.

Specifically, it seems you're having problems with this function:

[code]
void deleteNode(node*& pHead)
{
char szBuffer[255];
printf("\nENTER POSITION: ");
scanf("%s",szBuffer);
long lPos = atol(szBuffer);

node* pNext;
if (lPos == 0)
{
pNext = pHead;
delete pHead;
pHead = pNext;
}
else
{

// while (lCnt < lPos)
}

}
[/code]
First, not being an expert on C++, this syntax seems a bit strange to me...
[code]
void deleteNode(node*& pHead)
[/code]
You have a pointer to a reference? Seems a bit odd. They typically serve almost the same purpose, and you probably don't need to do that. I believe a reference might be the best way to go. Of course, I could be entirely wrong. [edit]I believe I am wrong, a reference to a pointer looks like the way to go here.[/edit]

So then, we'll go line-by-line into your first case -- if the position to delete is 0.

[code]
pNext = pHead;
delete pHead;
pHead = pNext;
[/code]
pNext = pHead
Assign the pointer value of the head to the pNext value.

delete pHead
Delete the pointer reference to the head.

pHead = pNext
Restore the pointer value of what was just the head to the pHead value.

I suggest you do this instead:
pNext = pHead->next; //(or is it pHead.next ?)
delete pHead;
pHead = pNext;

Your other case is something similar. While you haven't done it, think about it this way. Say you have already found the item, and have the pointer to it stored in a value called pNode.

[code]
pNode->prev->next = pNode->next; // again, do you need to use the dot operator?
pNode->next->prev = pNode->prev; // again, dot operator?
delete pNode;
[/code]

Hope that helps.
May 20, 2004, 12:22 AM
Myndfyr
Why was this sticky'd? Was it because I had a good, cogent answer? ^_^

Seriously, I'd like to know if I was right-on or not, because I'm still learning C++. :)
May 29, 2004, 6:51 PM
Fire
"You have a pointer to a reference? Seems a bit odd.

Nothing odd about it, I see that sytanx quite often in my classes.

Here is an example of some node assignemnts, hopefully this helps.

[code]
Here is for removing some node object.
/*----------------------------------------------------------------------
Purpose: This function frees memory allocated by a list.
Description: This function takes a parameter of a pointer to a
list pointer. The pointers are validated to be
none NULL, and then they are freed using a call
to free(). The nodes in the list are deleted
untill the list is empty, or there are no nodes.
If debugging is enabled, a message
will be displayed notifying the user that the
list has been deallocated. The list count is
decrimented, untill there is no longer remaining
lists to dellocate. The users is notified if the
pointers are erreneous or non-existant.
Input: **lpp: A pointer to a list pointer
Result: The list and its nodes are freed from memory using
free().
------------------------------------------------------------------------*/
void delete_List (List ** lpp) {

Node * newfront;

void * localdata; /* Used to store the data returned by private_remove*/

/* Validity check to see if this is not a null pointer */
if (lpp == NULL) {
fprintf(stderr,DELETE_NONEXIST);
return;
}

/* Validity check for *lpp, if it is non-existant, exit */
if (*lpp == NULL) {
fprintf(stderr, DELETE_NONEXIST);
return;
}

/* Display the debug message is enabled */
if (debug_on == TRUE) {
fprintf(stderr, LIST_DEALLOCATE, (*lpp)->list_count);
}

/* Delete all nodes on the list */
while (isempty_List(*lpp) == FALSE) {
newfront = (*lpp)->front->next;
localdata = private_remove_List(*lpp);
(*lpp)->delete_func(&localdata);
(*lpp)->front = newfront;
}

/* Free the memory using a call to free() */
free(*lpp);
*lpp = 0;

/* Decriment the stack count */
if (list_counter > 0)
list_counter--;

}

/*----------------------------------------------------------------------
Purpose: This function frees memory allocated by a list
but leaves the data in the heap via a call to
delete_Node, taking in a 0 as a parameter.
Description: This function takes a parameter of a pointer to a
list. The pointer is validated to be
none NULL. The front node is stored locally
in order to switch it back after operations have
occured. The data is also stored, and the
delete_Node functions is called passing a 0
in order to keep the data in the heap. The
list occupancy is decrimented, and the data
is returned.
Input: *this_list: A pointer to a list.
Result: The data at the node by which we called delete
Node is returned.
------------------------------------------------------------------------*/
static void * private_remove_List (List * this_list) {

Node * this_Node; /* Holds the front pointer */
void * nodedata; /* Holds the data at the working node */

/* Validity check the list */
if (this_list == NULL) {
return NULL;
}

/* List cannot be empty */
if (isempty_List(this_list)) {
fprintf(stderr, REMOVE_EMPTY);
return NULL;
}

/* Debugging messages */
if (debug_on == TRUE) {
fprintf(stderr, PRIVATE_LIST_REMOVE, this_list->list_count);
}

/* Need this front value */
this_Node = this_list->front;

/* Derefrence the data at that node */
nodedata = this_list->front->data;

/* Disconnect the node we are removing */
this_list->front->next->pre = this_list->front->pre;
this_list->front->pre->next = this_list->front->next;
this_list->front = this_list->front->next;
this_list->occupancy--;

/* Delete the node, but not the value */
delete_Node(&this_Node, 0);


return nodedata; /* Function executed successfully */

}

[/code]
Here is an example of inserting a node into a list.

[code]

/*----------------------------------------------------------------------
Purpose: This function will insert a node into the list.
Description: This function will first validate the list pointer.
If it is erreneous, then the user is notified with
an error message. If the location of insertion
is the front, then no special cases need to be
handled, simply a call to private insert. If the
point of insertion is the tail, the front needs
to be set to it's correct location. If the user
wants to insert into a specific location, the
function check_to_go_forward is called and returns
TRUE if the best approach to the loop would be
a loop forward. The function private insert is
then called.
Input: this_list: A list pointer.
where: The location of insertion.
item: The item to be pushed onto the stack
Result: The value is pushed onto the stack and non-zero
is returned.
------------------------------------------------------------------------*/
long insert (List * this_list, void * element, long where) {

long count = 0; /* Used to loop through the linked list */
Node * working; /* Holds the current node */

/* Validity check the paramenter list */
if (this_list == NULL) {
fprintf(stderr, INSERT_NONEXIST);
return 0;
}

/* Check for debugging messages */
if (debug_on == TRUE) {
fprintf(stderr,LIST_INSERT, this_list->list_count);
}

if (where < 0) /* Where can only be a posotive integer */
return 0;
/* The user wants to insert at the tail */
if (where == 0) {

private_insert(this_list, element); /* Call to insert */

/* Point the front to the corrent location */
this_list->front = this_list->front->next;

return 1;

} else if (where == 1) {

private_insert(this_list, element); /* Call to insert */

return 1;

}
else {

/* If the list is not empty */
if (isempty_List(this_list) == FALSE) {

working = this_list->front; /* Get the current front */

/* Call check_to_go_forward to decide which way to loop */

/* If the return value is true, we want top loop forward */
if ( (check_to_go_forward(this_list, where)) == TRUE) {
/* Loops untill we reach the desired location in the list */
for (count = 1; count < where; count++)
advance_next_List(this_list);
}
else
{
/* We want to loop from the end to now */
for (count = this_list->occupancy; count >= where; count--)
advance_pre_List(this_list);
}

private_insert(this_list, element);

this_list->front = working; /* The front is now the node we
currently added */
}

}

return 1;

}

/*----------------------------------------------------------------------
Purpose: This function will insert a node into the list,
which is invisibile to the user.
Description: This function will first validate the list pointer.
If it is erreneous, then the user is notified with
an error message. A Node is allocated via a call
to new_Node. If the list is empty, then the Node
pre and next is set to itself, and the front
points to the newly added node. If there are
existing nodes, then you set nodes pre to the
last node in the list. The nodes next will
be set to the list front. The list front will
be set to this node, and the pre and next will
be appropriately assigned.
Input: this_list: A list pointer.
element: The element used to allocate a node
item: The item to be pushed onto the stack
Result: A non-zero value is returned if the insert
was successful, otherwise 0 is returned.
------------------------------------------------------------------------*/
static long private_insert (List * this_list, void * element) {

Node * this_Node;
/* Create a new Node */
/* Validity check */
if (this_list == NULL) {
fprintf(stderr, INSERT_NONEXIST);
return 0;
}

this_Node = new_Node(element, this_list->copy_func);

if (debug_on == TRUE) { /* Display our debugging message */
fprintf(stderr, PRIVATE_LIST_INSERT, this_list->list_count);
}

/* If the list is empty, we calsl new_Node() */
if (isempty_List(this_list)) { /* Empty */

this_Node->pre = this_Node;
this_Node->next = this_Node;
this_list->front = this_Node;
this_list->occupancy++;
/* Return non-zero for success */
return 1;
}

this_Node->pre = this_list->front->pre;
this_Node->next = this_list->front;
this_list->front->pre = this_Node;
this_list->front->pre->pre->next = this_Node;
this_list->front = this_Node;
this_list->occupancy++;

return 1; /* Function executed successfully */

}

/*----------------------------------------------------------------------
Purpose: This function frees memory allocated by a list
but leaves the data in the heap via a call to
delete_Node, taking in a 0 as a parameter.
Description: This function takes a parameter of a pointer to a
list. The pointer is validated to be
none NULL. The front node is stored locally
in order to switch it back after operations have
occured. The data is also stored, and the
delete_Node functions is called passing a 0
in order to keep the data in the heap. The
list occupancy is decrimented, and the data
is returned.
Input: *this_list: A pointer to a list.
Result: The data at the node by which we called delete
Node is returned.
------------------------------------------------------------------------*/
static void * private_remove_List (List * this_list) {

Node * this_Node; /* Holds the front pointer */
void * nodedata; /* Holds the data at the working node */

/* Validity check the list */
if (this_list == NULL) {
return NULL;
}

/* List cannot be empty */
if (isempty_List(this_list)) {
fprintf(stderr, REMOVE_EMPTY);
return NULL;
}
/* Debugging messages */
if (debug_on == TRUE) {
fprintf(stderr, PRIVATE_LIST_REMOVE, this_list->list_count);
}

/* Need this front value */
this_Node = this_list->front;

/* Derefrence the data at that node */
nodedata = this_list->front->data;

/* Disconnect the node we are removing */
this_list->front->next->pre = this_list->front->pre;
this_list->front->pre->next = this_list->front->next;
this_list->front = this_list->front->next;
this_list->occupancy--;

/* Delete the node, but not the value */
delete_Node(&this_Node, 0);


return nodedata; /* Function executed successfully */

}
/*----------------------------------------------------------------------
Purpose: This function allocates memory for a node.
Description: This function takes in two parameters. The first
parameter is the element that you wush to copy, and
the second parameter tells the function how to
copy it. The function them returns the new node.
Input: element: The value to copy
copy_func: Used to tell the function how to copy
the data.
Result: The memory for a new node is allocated, and if
if copy function is unable to copy data, returns
the node. Otherwise, the node copies the data, and
returns this node.
------------------------------------------------------------------------*/
static Node* new_Node (void * element, void * (*copy_func) (void *)) {

/* allocate memory */
Node *this_Node = (Node *) malloc (sizeof (Node));

/* initialize memory */
this_Node->next = this_Node->pre = NULL;
this_Node->data = (copy_func) ? (*copy_func) (element) : element;

return this_Node;
}

/*----------------------------------------------------------------------
Purpose: This function will view an item in the list.
It is invisibile to the user.
Description: This function will first validate the list pointer.
If it is erreneous, then the user is notified with
an error message. This function Free memory and
assigns the incoming pointer to 0.
Input: *npp: A pointer to a list pointer
Result: Frees memory allocated by the list and assigns
it to point a zero. If the delete function
parameter is passed a 0, then it will not delete
the data at its current location. Otherwise,
the entire node is deleted.
------------------------------------------------------------------------*/
static void delete_Node (Node ** npp, void (*delete_func) (void *)) {

/* does the node exist??? */
if (!npp || !*npp) {
fprintf (stderr, DELETE_NONEXISTNODE);
return;
}

/* call function to delete element */
if (delete_func && (*npp)->data)
(*delete_func) (&((*npp)->data));

/* delete element */
free (*npp);

/* assign node to NULL */
*npp = NULL;
}

/*----------------------------------------------------------------------
Purpose: This function advances the front pointer backward
Description: This function will first validate the list pointer.
If it is erreneous, then the user is notified with
an error message. If the list is not empty, the
functions returns.
Input: this_list: A list pointer
Result: Advances the front pointer to previous node
-----------------------------------------------------------------------*/
void advance_pre_List (List * this_list) {
/* Validity check the paramenter list */
if (this_list == NULL) {
fprintf(stderr, ADVANCE_PRE_NONEXIST);
return ;
}

/* Check for debugging messages */
if (debug_on == TRUE) {
fprintf(stderr, ADVANCE_PRE, this_list->list_count);
}

if (isempty_List(this_list)) {
fprintf(stderr, ADVANCE_PRE_EMPTY);
return;
}

/* Advances the list one previous to the current front */
this_list->front = this_list->front->pre;

}

/*----------------------------------------------------------------------
Purpose: This function advances the front pointer forward
Description: This function will first validate the list pointer.
If it is erreneous, then the user is notified with
an error message. If the list is not empty, the
functions returns.
Input: this_list: A list pointer
Result: Advances the front pointer to the next node
-----------------------------------------------------------------------*/
void advance_next_List (List * this_list) {
/* Validity check the paramenter list */
if (this_list == NULL) {
fprintf(stderr, ADVANCE_NEXT_NONEXIST);
return;
}

/* Check for debugging messages */
if (debug_on == TRUE) {
fprintf(stderr, ADVANCE_NEXT, this_list->list_count);
}

/* The list cannot be empty */
if (isempty_List(this_list)) {
fprintf(stderr, ADVANCE_NEXT_EMPTY);
return;
}

/* Advances the list one after the current front */
this_list->front = this_list->front->next;

}



[/code]

Use this as a reference, hope that helps.
May 31, 2004, 10:04 AM
Moonshine
Or, alternatively (without using sh*tloads of code):

[code]
#include <list>

struct node
{

char* pszFirstName;
char* pszSurName;
char* pszCountry;
long nYear;
};

std::list<node *> MyList;

[/code]

:o
May 31, 2004, 4:02 PM
Maddox
std::list already has prev and next inherently, hence the reason it can iterate backwards and forwards. Only the actual data needs to be there.
May 31, 2004, 5:58 PM
Eibro
[quote author=Maddox link=board=30;threadid=6875;start=0#msg62961 date=1086026306]
std::list already has prev and next inherently, hence the reason it can iterate backwards and forwards. Only the actual data needs to be there.
[/quote]Yes, and you'll most likely not want to use node* in the list; that would make list iterators node**.
May 31, 2004, 6:24 PM
Maddox
No, "node *" should be correct.
May 31, 2004, 6:27 PM
Eibro
[quote author=Maddox link=board=30;threadid=6875;start=0#msg62971 date=1086028027]
No, "node *" should be correct.
[/quote]Eh? Either will work. It's just a matter of preference. std::list<node> vs. std::list<node*>
May 31, 2004, 6:39 PM
Moonshine
If you just use list<node>, how would you create list items dynamically (e.g. new node)? That seems like the whole point of a list in most cases to me. Also, it wouldn't even matter if the list iterators were node**, because all you need to do is use list<node*>::iterator, and not worry about any syntax at the lower level.

And anyways, about that leaving pointers in the struct: I didn't even look at that guy's massive list (or the node struct). I just copy and pasted the struct from his code. You guys get the idea, and I'm sure you'll get over it.. ::)

The point of that post was to point out the STL was easier, obviously. I don't even know why you bothered arguing semantics over it; it doesn't even matter.

Edit: Got rid of the redundant pointers, hope it'll make you guys sleep better. :)
June 1, 2004, 7:38 PM
Eibro
[quote author=Moonshine link=board=30;threadid=6875;start=0#msg63096 date=1086118691]
If you just use list<node>, how would you create list items dynamically (e.g. new node)? That seems like the whole point of a list in most cases to me.[/quote]
By calling nodes constructor. eg. mylist.push_back( node( arg1, arg2 ) ); where mylist is std::list<node>.

[quote]Also, it wouldn't even matter if the list iterators were node**, because all you need to do is use list<node*>::iterator, and not worry about any syntax at the lower level.[/quote]Yes, it would matter. To access elements of node, you'd need to do (*listiter)->member;

Again, these discussions don't really pertain to the original posters question. Oh well.
June 1, 2004, 8:06 PM
Moonshine
[quote author=Eibro[yL] link=board=30;threadid=6875;start=0#msg63102 date=1086120366]
[quote author=Moonshine link=board=30;threadid=6875;start=0#msg63096 date=1086118691]
If you just use list<node>, how would you create list items dynamically (e.g. new node)? That seems like the whole point of a list in most cases to me.[/quote]
By calling nodes constructor. eg. mylist.push_back( node( arg1, arg2 ) ); where mylist is std::list<node>.

[quote]Also, it wouldn't even matter if the list iterators were node**, because all you need to do is use list<node*>::iterator, and not worry about any syntax at the lower level.[/quote]Yes, it would matter. To access elements of node, you'd need to do (*listiter)->member;

Again, these discussions don't really pertain to the original posters question. Oh well.
[/quote]

Hmmk, but that way is definitely a lot less versatile/clear than if you use pointers (in fact I've personally never seen it used). For one, you're totally limited to only passing constructor parameters (vs. being able to create a new object before insertation, and doing further manipulation before passing it).

And maybe you shouldn't have critiqued my original post (when you were wrong about me wanting to use node * anyways), and made it go off topic. My post was on-topic; providing advice to fire that the STL is easier to use.
June 2, 2004, 12:46 AM
Eibro
[quote author=Moonshine link=board=30;threadid=6875;start=0#msg63158 date=1086137203]
[quote author=Eibro[yL] link=board=30;threadid=6875;start=0#msg63102 date=1086120366]
[quote author=Moonshine link=board=30;threadid=6875;start=0#msg63096 date=1086118691]
If you just use list<node>, how would you create list items dynamically (e.g. new node)? That seems like the whole point of a list in most cases to me.[/quote]
By calling nodes constructor. eg. mylist.push_back( node( arg1, arg2 ) ); where mylist is std::list<node>.

[quote]Also, it wouldn't even matter if the list iterators were node**, because all you need to do is use list<node*>::iterator, and not worry about any syntax at the lower level.[/quote]Yes, it would matter. To access elements of node, you'd need to do (*listiter)->member;

Again, these discussions don't really pertain to the original posters question. Oh well.
[/quote]

Hmmk, but that way is definitely a lot less versatile/clear than if you use pointers (in fact I've personally never seen it used). For one, you're totally limited to only passing constructor parameters (vs. being able to create a new object before insertation, and doing further manipulation before passing it).

And maybe you shouldn't have critiqued my original post (when you were wrong about me wanting to use node * anyways), and made it go off topic. My post was on-topic; providing advice to fire that the STL is easier to use.
[/quote]Limited how?
node mynode;
mynode.somefn();
mylist.push_back( mynode );

Maddox orginally critiqued your post, not me.
June 2, 2004, 1:49 AM
Moonshine
[quote]
Limited how?
node mynode;
mynode.somefn();
mylist.push_back( mynode );
[/quote]

Umm, that'll go out of scope if you do it that way. Which is quite dangerous, btw ;)

[quote]
Maddox orginally critiqued your post, not me.
[/quote]

That may be true, but you also independantly made your own point critiquing my post. Which means you're just as bad as him, gg :P
June 2, 2004, 8:23 AM
Eibro
[quote author=Moonshine link=board=30;threadid=6875;start=15#msg63243 date=1086164617]
[quote]
Limited how?
node mynode;
mynode.somefn();
mylist.push_back( mynode );
[/quote]

Umm, that'll go out of scope if you do it that way. Which is quite dangerous, btw ;)
[/quote]No. You don't understand. There is nothing dangerous about that code. The copy constructor will be invoked to create a new variable on the list. The original will go out of scope.
June 2, 2004, 3:40 PM
Moonshine
Okay so it invokes the copy constructor (I didn't even test it, and forgot about that). However, that's way less efficient than using a pointer; copying the whole object over when you can simply point to it is moronic. I guess that's why I stay away from that way in the first place, it's needlessly less efficient.

So maybe you shouldn't suggest preferring not using pointers when they're way more efficient in the future.
June 2, 2004, 10:09 PM
Adron
[quote author=Moonshine link=board=30;threadid=6875;start=15#msg63322 date=1086214194]
Okay so it invokes the copy constructor (I didn't even test it, and forgot about that). However, that's way less efficient than using a pointer; copying the whole object over when you can simply point to it is moronic. I guess that's why I stay away from that way in the first place, it's needlessly less efficient.

So maybe you shouldn't suggest preferring not using pointers when they're way more efficient in the future.
[/quote]

There are advantages and disadvantages. If the object is big, copying the whole object over is bad. Then you should write your code to create the object in the list first and assign values in it later. That way you are doing everything with the highest efficiency.

However, for a small object, invoking the copy constructor won't be a big issue. Something like a std::string will copy very fast.

Storing the object in the list will also be more memory efficient. Instead of having two allocations per list item, there'll be just a single allocation. That's way more efficient.
June 2, 2004, 10:17 PM

Search