vector iterators

E

edu.mvk

Hi, i have the following code which updates the vector of strings(
p_vector ) each time it goes into the loop

for the first iteration we have only one string in the vector. But in
the while loop we are updating the vector and adding few more strings
at the end.

I'm expecting that In the second iteration the "it" should point to the
updated vector, but it is pointing to the "NULL".


for(vector<string>::iterator it = p_vector.begin(); it !=
p_vector.end(); it++)
{
LogInfo(("\nNext directory %s\n",it->c_str()));
pDirStream = opendir(it->c_str());
LogInfo(("\n%s Directory
opened\n",it->c_str()));
while(pDirEntry = readdir(pDirStream) )
{
if( pDirEntry->d_type == DT_DIR )
{
count++;
if(count>2)
{
l_Name.append("/");

l_Name.append(string(pDirEntry->d_name));
LogInfo(("\n\nThe
subpath is: %s\n",l_Name.c_str()));

p_vector.push_back(l_Name);
l_Name.assign(p_Name);
}
}
}
closedir(pDirStream);
count = 0;
}


Please explain why the "it" pointing to NULL and how can i point to the
updated vector in the second and subsequent iterations of the for loop.

Thanks,
 
S

Stuart Redmann

edu.mvk said:
Hi, i have the following code which updates the vector of strings(
p_vector ) each time it goes into the loop

for the first iteration we have only one string in the vector. But in
the while loop we are updating the vector and adding few more strings
at the end.

I'm expecting that In the second iteration the "it" should point to the
updated vector, but it is pointing to the "NULL".
for(vector<string>::iterator it = p_vector.begin(); it !=
p_vector.end(); it++)
{
LogInfo(("\nNext directory %s\n",it->c_str()));
pDirStream = opendir(it->c_str());
LogInfo(("\n%s Directory
opened\n",it->c_str()));
while(pDirEntry = readdir(pDirStream) )
{
if( pDirEntry->d_type == DT_DIR )
{
count++;
if(count>2)
{
l_Name.append("/");

l_Name.append(string(pDirEntry->d_name));
LogInfo(("\n\nThe
subpath is: %s\n",l_Name.c_str()));

p_vector.push_back(l_Name);
l_Name.assign(p_Name);
}
}
}
closedir(pDirStream);
count = 0;
}

Above code is:
a) badly formatted, and
b) non-compilable.
Please try to avoid these issues in future.
Please explain why the "it" pointing to NULL and how can i point to the
updated vector in the second and subsequent iterations of the for loop.

After inserting into a vector, your iterators may become invalid
(especially if the vector needs to re-allocate). You should rethink your
algorithm. See the following example:

#include <vector>
#include <string>

using namespace std;

int main ()
{
vector<string> p_vector;
p_vector.push_back ("Test");
for(vector<string>::iterator it = p_vector.begin();
it != p_vector.end(); it++)
{
if (p_vector.size () < 10)
{
// Determine the position of the iterator inside
// the vector, so that we can set the iterator
// to the same position after inserting.
int Offset = it - p_vector.begin ();
p_vector.push_back("Test2");
it = p_vector.begin () + Offset;
}
}
return 0;
}

It may be more suitable to leave out iterators altogether and use an
index variable for direct access.

Regards,
Stuart
 
K

Kai-Uwe Bux

edu.mvk said:
Hi, i have the following code which updates the vector of strings(
p_vector ) each time it goes into the loop

for the first iteration we have only one string in the vector. But in
the while loop we are updating the vector and adding few more strings
at the end.

I'm expecting that In the second iteration the "it" should point to the
updated vector, but it is pointing to the "NULL".


for(vector<string>::iterator it = p_vector.begin(); it !=
p_vector.end(); it++)
{
LogInfo(("\nNext directory %s\n",it->c_str()));
pDirStream = opendir(it->c_str());
LogInfo(("\n%s Directory
opened\n",it->c_str()));
while(pDirEntry = readdir(pDirStream) )
{
if( pDirEntry->d_type == DT_DIR )
{
count++;
if(count>2)
{
l_Name.append("/");

l_Name.append(string(pDirEntry->d_name));
LogInfo(("\n\nThe
subpath is: %s\n",l_Name.c_str()));

p_vector.push_back(l_Name);

This push_back() operation invalidates all iterators to the vector
p_vector() whenever p_vector needs to reallocate its data to accommodate
for the increased number of elements.
l_Name.assign(p_Name);
}
}
}
closedir(pDirStream);
count = 0;
}


Please explain why the "it" pointing to NULL and how can i point to the
updated vector in the second and subsequent iterations of the for loop.

The most easy way to cope with your problem might be to rewrite the loop
using an index instead of an iterator:

for(vector<string>::size_type i = 0; i < p_vector.size(); ++i ) {
LogInfo(("\nNext directory %s\n", p_vector.c_str()));
pDirStream = opendir(p_vector.c_str());
LogInfo(("\n%s Directory opened\n",p_vector.c_str()));
while(pDirEntry = readdir(pDirStream) ) {
if( pDirEntry->d_type == DT_DIR ) {
count++;
if(count>2) {
l_Name.append("/");

l_Name.append(string(pDirEntry->d_name));
LogInfo(("\n\nThe subpath is: %s\n",l_Name.c_str()));

p_vector.push_back(l_Name);
l_Name.assign(p_Name);
}
}
}
closedir(pDirStream);
count = 0;
}


Best

Kai-Uwe Bux
 
S

Salt_Peter

edu.mvk said:
Hi, i have the following code which updates the vector of strings(
p_vector ) each time it goes into the loop

for the first iteration we have only one string in the vector. But in
the while loop we are updating the vector and adding few more strings
at the end.

I'm expecting that In the second iteration the "it" should point to the
updated vector, but it is pointing to the "NULL".


for(vector<string>::iterator it = p_vector.begin(); it !=
p_vector.end(); it++)
{
LogInfo(("\nNext directory %s\n",it->c_str()));
pDirStream = opendir(it->c_str());
LogInfo(("\n%s Directory
opened\n",it->c_str()));
while(pDirEntry = readdir(pDirStream) )
{
if( pDirEntry->d_type == DT_DIR )
{
count++;
if(count>2)
{
l_Name.append("/");

l_Name.append(string(pDirEntry->d_name));
LogInfo(("\n\nThe
subpath is: %s\n",l_Name.c_str()));

p_vector.push_back(l_Name);
l_Name.assign(p_Name);
}
}
}
closedir(pDirStream);
count = 0;
}


Please explain why the "it" pointing to NULL and how can i point to the
updated vector in the second and subsequent iterations of the for loop.

It doesn't matter, you are invoking undefined behaviour. One does not
modify a container while you are iterating through it - the iterators
become invalid (which is a good thing - what if vector resized itself
to somewhere else in memory?).
There is a simple solution, however. make a new vector before the loop
and load that while you iterate through the loop, then push_back the
new data once you have left the loop.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top