472,328 Members | 983 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,328 software developers and data experts.

List iterator assignment fails, assert iterator not dereferencable

All

Apologies for cross posing this but I am not sure if this is a VC 8 STL
bug or simply an invalid use of the iterator.

I have a PCI card access class which basically abstracts a third party
library from the higher level classes. This low level class is used to
allocate locked pages of memory before doing a DMA. The third party
library locks memory and returns a pointer to an internal structure,
which we can simply cast to a (void *).

My original intention was to have the low level PCI access class store
these third party pointers away in a list so that if the class is
destructed and the list is not empty (explicit unlocks have not been
performed) we can step through the list and tidy up nicely. The list is
defined in the class as:

// Some defines to wrap up the list/iterator type definitions.
typedef void * PCICardDMABufObject;
typedef list<PCICardDMABufObjectPCICardDMABufHandleList;
typedef PCICardDMABufHandleList::iterator PCICardDMABufHandle;

// List type in class.
PCICardDMABufHandleList *m_pDMAPageList;

The list is dynamically allocated in the constructor as:

m_pDMAPageList = new PCICardDMABufHandleList();

Along with storing the void pointers internally we also want to pass
these back to the higher level class which wraps up what the specific
PCI card can do, in this case it has a number of DMA channels. This
higher level class calls the low level classes lock function and
receives back an iterator of the void pointer stored in the low level
classes list as follows:

// List iterator
PCICardDMABufHandle hLockedBufHandle;

// Call to low level PCI class. Iterator returned in last parameter.
status = m_pPCICardInst->LockDMABuffer(pUserBufStartAddr, bytesToLock,
dmaDir, &pDMADescPageBufAddr[dmaDescPageBufIndex], &numDMAPages,
hLockedBufHandle);

The function prototype in the low level class for this is:

PCIStatus LockDMABuffer(void *pDataBuf, unsigned int length,
PCICardDMADir dmaDir,
PCICardDMAPage *pDMAPages,
unsigned int *pNumPages,
PCICardDMABufHandle &hDMABufHandle);

Later on in the same function we assign the function we assign the list
iterator to a dynamically allocated array of list iterators for the
current DMA channel as follows:

// Store iterator away in higher level class for channel.
m_phUserDMABufHandles[m_numUserDMABufHandles] = hLockedBufHandle;
m_numUserDMABufHandles++;

The array has a fixed max length defined by the largest DMA transfer.
The array is defined in the higher level class as:

PCICardDMABufHandle *m_phUserDMABufHandles;

and is allocated at construction with:

m_phUserDMABufHandles = new
PCICardDMABufHandle[PCI_MAX_NUM_USER_DMA_BUFFER_HANDLES];

The higher level class needs to keep track of which locked pages are
associated with a give DMA transfer.

This all works fine up to the point I benchmarked 4 DMA channels from 4
threads. I carefully protected the low level classes list access, both
read and write, with a mutex to prevent multiple threads updating the
list together and from some debugging output to stderr I am confident
that this is valid.

The problem I get is when I come to access the iterator stored in the
high level classes array of iterators once a DMA has completed and I
need to unlock all the buffers. The low level class is passed the
iterator back by the high level class, and it tries to dereference the
iterator to get the void pointer.

Now this is where the problem takes on an implementation specific
stance. The code asserts in VC 2005 with an "iterator not
dereferenceable" at:

if (this->_Mycont == 0
|| _Ptr == ((_Myt *)this->_Mycont)->_Myhead)
{
_DEBUG_ERROR("list iterator not dereferencable");
_SCL_SECURE_TRAITS_OUT_OF_RANGE;
}

_Mycont is 0 when it fails.

This however is not where the problem actually starts, this is way back
when the buffer was originally locked and assigned to the array of
iterators m_phUserDMABufHandles. If I setup a conditional break point in
VC after the point of assignment at :

m_phUserDMABufHandles[m_numUserDMABufHandles] = hLockedBufHandle;

to test _Mycont of m_phUserDMABufHandles then after say 8000 iterations,
in 4 threads, the breakpoint fires as _Mycont is 0. The _Mycont of the
hLockedBufHandle however is valid, none 0. If I deliberately move the
point of execution back to the assignment and try again, the assignment
works and _Mycont gets a valid value.

So my problem is why does this not work? And why does it not work after
working for quite some considerable number of iterations previously?

Interestingly if I pass the
m_phUserDMABufHandles[m_numUserDMABufHandles] location directly to the
LockDMABuffer() call in place of the local hLockedBufHandle it seems to
work fine!

Am I doing something bad here with iterators? There seems to be few
references to what exactly you can and cannot do with an iterator. Most
references to "not dereferenceable" relate to already erased elements in
say vectors, this however is a list and from my understanding an
iterator for an element will remain valid regardless of adds or deletes
around it in the list. I can also see the element in the list in the
debugger so I know it is valid, it just seems to be the iterator which
is broken. It almost looks like a problem with the assignment of the
iterator.

Any suggestions, help, sympathy much appreciated.

David.
Oct 8 '07 #1
1 6119
David Bilsby wrote:
The code asserts in VC 2005 with an "iterator not
dereferenceable" at:

if (this->_Mycont == 0
|| _Ptr == ((_Myt *)this->_Mycont)->_Myhead)
{
_DEBUG_ERROR("list iterator not dereferencable");
_SCL_SECURE_TRAITS_OUT_OF_RANGE;
}

_Mycont is 0 when it fails.
That basically means that either you didn't get this iterator from a
container or (maybe) that the container ceased to exist. Note that I'm not
sure with the latter part, it would require that a dying container zeroes
all the back pointers in its iterators and I'm not sure if the debug
variant of VC8's stdlib does that. However, that should be trivial to find
out:

typedef ... container;

container::iterator it;
*it; // should fail, iterator not from container
{
container c(1);
it = c.begin();
*it; // okay, container still alive
}
*it; // should fail, container ceased to exist
Otherwise, can you distill a minimal example from your code?

Uli

Oct 8 '07 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

13
by: Santanu Chatterjee | last post by:
Hello everybody, I am very new to python. I have a query about list in python. Suppose I have a list a = ,5,6,7,,11,12] I want to know if...
1
by: John | last post by:
Hi, all This is a question about the iterator on list In this code below, I check the time out for all the connected socket in a list. The...
8
by: freckred76 | last post by:
Hi, I think this might be a VC++ problem. I am using Microsoft Visual Studio 2005 Full Version (8.0). I have a simple for loop that iterates...
4
by: Johan Pettersson | last post by:
Hi, I'm trying to "port" a project from VC++ 2003 to VC++ 2005 (Express Edition). This project contains the following code on several places (It...
3
by: janzon | last post by:
Hi! Sorry for the bad subject line... Here's what I mean. Suppose we deal with C++ standard integers lists (the type is indifferent). We have a...
61
by: warint | last post by:
My lecturer gave us an assignment. He has a very "mature" way of teaching in that he doesn't care whether people show up, whether they do the...
1
by: ashishbhatt12 | last post by:
Hi All, I am using list class in my project(MFC Application). I have made list like ..... typedef std::list rectlist; // Here list is of type...
2
by: Piojolopez | last post by:
Hello guys, I have a problem with this code, the program is the resolution of Sudoku grid, the grid in my program is a vector of STL,and i use a list...
1
by: tonylamb | last post by:
Hi All, I seem to be getting an error with my code when running Intel C++ compiler via Visual Studio 2005. The error generated is...
0
by: tammygombez | last post by:
Hey fellow JavaFX developers, I'm currently working on a project that involves using a ComboBox in JavaFX, and I've run into a bit of an issue....
0
better678
by: better678 | last post by:
Question: Discuss your understanding of the Java platform. Is the statement "Java is interpreted" correct? Answer: Java is an object-oriented...
0
by: teenabhardwaj | last post by:
How would one discover a valid source for learning news, comfort, and help for engineering designs? Covering through piles of books takes a lot of...
0
by: Kemmylinns12 | last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and...
0
by: CD Tom | last post by:
This happens in runtime 2013 and 2016. When a report is run and then closed a toolbar shows up and the only way to get it to go away is to right...
0
by: CD Tom | last post by:
This only shows up in access runtime. When a user select a report from my report menu when they close the report they get a menu I've called Add-ins...
0
jalbright99669
by: jalbright99669 | last post by:
Am having a bit of a time with URL Rewrite. I need to incorporate http to https redirect with a reverse proxy. I have the URL Rewrite rules made...
0
by: Matthew3360 | last post by:
Hi there. I have been struggling to find out how to use a variable as my location in my header redirect function. Here is my code. ...
1
by: Matthew3360 | last post by:
Hi, I have a python app that i want to be able to get variables from a php page on my webserver. My python app is on my computer. How would I make it...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.