Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check whether iterators form a contiguous memory zone?

I currently have the following function to read an array or a vector of raw data (_readStream is a std::ifstream) :

template<typename IteratorType> 
inline bool MyClass::readRawData(
    const IteratorType& first, 
    const IteratorType& last, 
    typename std::iterator_traits<IteratorType>::iterator_category* = nullptr
    )
{
    _readStream.read(reinterpret_cast<char*>(&*first), (last-first)*sizeof(*first));
    return _readStream.good();
}

First question : does this function seem ok for you ?

As we read directly a block of memory, it will only work if the memory block from first to last is contiguous in memory. How to check that ?

like image 653
Vincent Avatar asked Sep 30 '12 03:09

Vincent


People also ask

What is a checked iterator?

A checked iterator refers to an iterator that calls invalid_parameter_handler if you attempt to move past the boundaries of the container. For more information about invalid_parameter_handler, see Parameter Validation. The iterator adaptors that support checked iterators are checked_array_iterator Class and unchecked_array_iterator Class.

What is contiguous iterator in c++20?

contiguous_iterator is modeled by every pointer type to complete object type. Iterator types in the standard library that are required to satisfy the LegacyContiguousIterator requirements in C++17 are also required to model contiguous_iterator in C++20.

Why is it difficult to obtain large contiguous memory regions from kernel?

As the physical pages must be contiguous (not the case for user space malloced memory). It is often difficult to obtain large contiguous memory regions from the kernel, especially the longer the system is up and running.

What does _iterator_debug_level mean?

If _ITERATOR_DEBUG_LEVEL is defined as 1 or 2, unsafe use of iterators causes a runtime error and the program is terminated. If defined as 0, checked iterators are disabled. By default, the value for _ITERATOR_DEBUG_LEVEL is 0 for release builds and 2 for debug builds. Older documentation and source code may refer to the _SECURE_SCL macro.


Video Answer


2 Answers

Leaving aside your sample function, you can never be completely sure that iterators will form a contiguous memory without checking the address of every element between the two.

A reasonable sanity test, though, would be to just check if the memory area between the two is the same as the count between the two:

assert(&*last - &*first == last - first &&
    "Iterators must represent a contiguous memory region");
like image 195
Cameron Avatar answered Oct 13 '22 00:10

Cameron


n4183 is a paper that goes over the idea of adding a contiguous iterator trait. It is currently under consideration for C++1z (hopefully C++17).

Under it, you can do std::is_contiguous_iterator<It>::value and get if It is a contiguous iterator or not. (This will require support from the designer of the iterator).

like image 35
Yakk - Adam Nevraumont Avatar answered Oct 12 '22 23:10

Yakk - Adam Nevraumont