Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / August 2006

Tip: Looking for answers? Try searching our database.

need some help with list::end ()

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Abubakar - 15 Aug 2006 12:30 GMT
Hi all,

I'm using stl's list to store some file names. Its declared as:

list < char * > filenames;
i enumerate the list by using:

list < char * >::const_iterator filename;

filename = filenames.begin();

than I simply do a filename++ to go to the next item.....

I check for filenames.end() in an *if* condition somewhere in my code to
check if I'm dealing with the last item of the list. The code to do this was
working fine. But now due to some change in my code, some of the list items
are deleted *before* the filenames.end() check. I have noticed that this
check now never evaluates to true although I know in the debugger that I'm
standing at the last item. I'm sure I'm missing some basic concept here. How
can I check now that this is the last item of the list?

I'm using vc++ 2k5 total unmanaged.

Regards,

-ab.
Bo Persson - 15 Aug 2006 15:04 GMT
> Hi all,
>
[quoted text clipped - 22 lines]
> here. How
> can I check now that this is the last item of the list?

How are you deleting the items? Just doing filenames.erase(filename)
invalidates the iterator to the deleted object.

You should be doing something like

  if (some_condition)
     filename = filenames.erase(filename);
  else
     ++filename;

This will *either* use the returned iterator to the next object, or
increment the current iterator. You should do one, but not both!  :-)

Bo Persson
Abubakar - 16 Aug 2006 06:49 GMT
Sorry for the late reply.

> How are you deleting the items? Just doing filenames.erase(filename)
> invalidates the iterator to the deleted object.

I use the "remove" method.

I have the following declaration:

list<char * >::const_iterator name, prev;

at some point I do:

prev = name;
name ++;
filenames.remove ( *prev );

and this is how I remove the items.

regards,
-ab.

> > Hi all,
> >
[quoted text clipped - 37 lines]
>
> Bo Persson
Carl Daniel [VC++ MVP] - 16 Aug 2006 15:16 GMT
> Sorry for the late reply.
>
[quoted text clipped - 14 lines]
>
> and this is how I remove the items.

If you have duplicates in your list, the call to remove will remove more
than one of them at a time, including possibly the one now referenced by
"name".  Use the loop that Bo suggested:

  if (some_condition)
     filename = filenames.erase(filename);
  else
     ++filename;

that's the canonical way to iterate through a list removing some elements as
you go.

-cd
Carl Daniel [VC++ MVP] - 16 Aug 2006 15:47 GMT
>> Sorry for the late reply.
>>
[quoted text clipped - 26 lines]
> that's the canonical way to iterate through a list removing some
> elements as you go.

Also, how are you adding the items to the list?  Since you're storing raw
char*'s, the list isn't managing the memory occupied by the strings - you
are.  You should consider changing to a std::list<std::string> instead.

-cd
Abubakar - 16 Aug 2006 17:06 GMT
> char*'s, the list isn't managing the memory occupied by the strings - you
> are.
list <char * > filenames ;

WIN32_FIND_DATAA finddata;
//emailblockslocation
HANDLE filehandle = FindFirstFileA ( m_folderlocation , & finddata );
char * filename = NULL;
do
{
 if ( (finddata.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE )==
FILE_ATTRIBUTE_ARCHIVE )
 {
  filename = new char [500];
  strcpy ( filename , finddata.cFileName );
  filenames.push_back ( filename );

 }

} while ( FindNextFileA( filehandle, & finddata ) != 0 );
FindClose ( filehandle );

> >> Sorry for the late reply.
> >>
[quoted text clipped - 32 lines]
>
> -cd
Carl Daniel [VC++ MVP] - 17 Aug 2006 04:29 GMT
>> char*'s, the list isn't managing the memory occupied by the strings
>> - you are.
[quoted text clipped - 10 lines]
>  {
>   filename = new char [500];

This memory is being leaked when you remove an item from the list - nothing
will call delete[] on it (unless there's yet more code that you haven't
shown that does delete it).

>   strcpy ( filename , finddata.cFileName );
>   filenames.push_back ( filename );
[quoted text clipped - 3 lines]
> } while ( FindNextFileA( filehandle, & finddata ) != 0 );
> FindClose ( filehandle );

I'd recommend changing your container to std::list<std::string>, then the
memory for the string will be automatically freed when an item is removed
from the list.

-cd
Abubakar - 17 Aug 2006 08:15 GMT
> I'd recommend changing your container to std::list<std::string>, then the
> memory for the string will be automatically freed when an item is removed

yes I was going to write the code for the deletion of char *, but I got
stuck in that filenames.end() condition which btw is still not working. This
std::string idea is good and will reduce my code.

-Ab.

> >> char*'s, the list isn't managing the memory occupied by the strings
> >> - you are.
[quoted text clipped - 28 lines]
>
> -cd
Tamas Demjen - 17 Aug 2006 18:33 GMT
> yes I was going to write the code for the deletion of char *, but I got
> stuck in that filenames.end() condition which btw is still not working.

Have you tried what Bo and Carl recommended? Here's a complete example:

for(std::list<std::string>::iterator filename = filenames.begin();
    filename != filenames.end(); )
{
   if(FileNeedsToBeDeletedCondition)
      filename = filenames.erase(filename);
   else
      ++filename;
}

If have a radically different mechanism, it's probably not going to work.

I strongly recommend the book Effective STL by Scott Meyers, which
discusses this and dozens of other tricks with STL containers.

Tom
Abubakar - 19 Aug 2006 17:04 GMT
Hi,

I have solved the problem by using the list::back() method. As back()
represents the last item in the list, so thats what I was looking for. The
problem with what I was doing was my lack of understanding with the list's
"end" method. I thought that the "end" represents the last item, which is
not correct.

Thanks for the book recommendation!

Regards,

-Ab.

PS: again, sorry for having replied so late,,,, I hate my replying-late
habbit !!!

> > yes I was going to write the code for the deletion of char *, but I got
> > stuck in that filenames.end() condition which btw is still not working.
[quoted text clipped - 16 lines]
>
> Tom
Abubakar - 16 Aug 2006 17:21 GMT
Hi,

Ok I'll try the *remove* method of the list and if I still cant get the
begin() method to work right I'll get back to this post.

Regards,

-ab.

> > Sorry for the late reply.
> >
[quoted text clipped - 28 lines]
>
> -cd

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.