Memory Access Error Inserting Point Into nD Delaunay Triangulation - windows

I'm attempting to implement Schlomer's Max Min Dist sets in N dimensions for a project I'm working on using CGAL's nD Delaunay Triangulation for the algorithm. I'm able to compile and run the example code, but when incorporating the triangulation into my set's class, I get memory access errors after inserting a few points. As far as I can tell, besides the fact that the triangulation is living in the class instance memory space and not main, I'm not diverging significantly from the example code. I am using Dynamic_Dimension_tag instead of a compile-time fixed triangulation, but I tweak the example code to do the same and it's fine. I'll sample the header and source below, detailing the method I'm using to do the point additions. Another set of more experienced eyes would be greatly appreciated.
Header:
#include <boost/container/vector.hpp>
#include <CGAL\Epick_d.h>
#include <CGAL\Delaunay_triangulation.h>
#include <iostream>
using namespace boost::container;
typedef CGAL::Triangulation<CGAL::Epick_d<CGAL::Dynamic_dimension_tag>> T;
class DllExport MaxMinDist
{
public:
MaxMinDist(int);
const vector<T::Point>& points() const;
int createPointsFromData(const vector<double>&);
int dimension(void) const;
int size(void) const;
private:
T dt_;
vector<T::Point> points_;
double localMinDist(const T::Point&);
double globalMinDist(void);
double averageMinDist(void);
void iterateGlobalFPO(void);
void iterateLocalFPO(void);
double toroidalDistanceOnAxis(double, double);
double toroidalSquaredDistance(const T::Point&, const T::Point&);
};
Source:
int MaxMinDist::createPointsFromData(const vector<double>& data)
{
// data supplied doesn't match the dimension
if (data.size() % dimension() != 0) return -1;
// break up the data into points
points_.reserve(data.size() % dimension());
for (auto iter = data.begin(); iter != data.end(); iter += dimension()) {
T::Point p(iter, iter + dimension());
points_.push_back(p);
}
// add the points to the triangulation
T::Vertex_handle hint;
int i = 0;
for (auto pt_iter = points_.begin(); pt_iter != points_.end(); ++pt_iter) {
std::cout << "Processing: " << *pt_iter << ", " << ++i << " of " << int(points_.size()) << std::endl;
if (T::Vertex_handle() != hint) {
hint = dt_.insert(*pt_iter, hint);
}
else {
hint = dt_.insert(*pt_iter);
}
}
return 0;
The function that is throwing the exception is NT_Convertor, defined in NT_Convertor.h in the CGAL namespace.
NT_Convertor
template < class NT1, class NT2 >
struct NT_converter
: public CGAL::unary_function< NT1, NT2 >
{
NT2
operator()(const NT1 &a) const
{
return NT2(a); <-- source of exception
}
};
Ok, further development.
Examining the stack frames, I noted that the library holding the excepting function is "C:\Program Files\Autodesk\Maya2018\bin\libgmp-10.dll". The main project is a plugin for Autodesk Maya. Unfortunately, that self-same library is part of the CGAL install. CGAL has its own copy of the DLL in the linking folder. I removed the MaxMinDistSet class from the project to a new separate project, just a library for itself notably without the includes or linking from OpenMaya. Testing that separate project was successful. I was able to add all points in the test fixture to the Triangulation. So the issue appears to be a conflict between CGAL's libgmp-10.dll and Maya's libgmp-10.dll.
The next question then becomes, can CGAL be build to statically embed its version of the library, or is there a more correct way to resolve the conflict?

Related

C++: Get state of linear congruential generator

It seems that if I write
#include <random>
std::minstd_rand engine(1);
std::cout << engine;
then this prints out the internal state of the engine (which is a linear congruential generator). Right now the state equals the seed (1), but if I call a random number and print out engine, it returns some large number, which is probably the state.
How do I actually get the state, in a variable?
Use a string stream instead of stdout. Example:
#include <sstream>
...
std::ostringstream os;
os << engine;
string mystate = os.str();
The o in ostringstream is for output.
The state should be last random number generated, which is why there is not an easier way to do this. It's not as ideal as something like int a; a << engine, but it'll have to do. If you need it that often, make the stringstream operation a function (Including perhaps a conversion from string to integer). You can also typedef a pair of engine/integer with the integer being the state, and make a couple of methods so it's autoset every generation call if you need the performance.
If you don't care about the state, and just want it for the future, do
int engineState = engine();
Now you have the state. Though it's not the same as what it was before, it might not matter depending on your use case.
Output from linear congruential RNG is the state. Or, as alreadynoted, use operator<< to output and convert state
Code
#include <random>
#include <iostream>
#include <sstream>
int main() {
auto engine = std::minstd_rand{ 1 };
auto q = engine();
auto os = std::ostringstream{};
os << engine;
auto r = std::stoul(os.str()); // use ul to fit output
std::cout << q << " " << os.str() << " " << r << '\n';
return 0;
}
prints
48271 48271 48271
Alternative might be if particular implementation implements discard properly in O(log2(N)) time, according to paper by F.Brown https://laws.lanl.gov/vhosts/mcnp.lanl.gov/pdf_files/anl-rn-arb-stride.pdf. In such case you could move one position back, call RNG again and get your state as output.
Compiler and library I use - Visual C++ 2017 15.7 - has not implemented discard in such way, and useless for moving back.
LCGs consist of a simple state that is represented by a single integer.
This means you can treat this pointer as a pointer to an integer.
Below, I have provided an example of a template function that gets
the state (seed) of an engine and even works for classes deriving LCGs.
#include <random>
template <class T, T... v>
T getSeed(std::linear_congruential_engine<T, v...>& rand) {
static_assert(sizeof(rand) == sizeof(T));
return *reinterpret_cast<T*>(&rand);
}
#include <iostream>
int main() {
std::minstd_rand engine(19937);
auto seed = getSeed(engine);
std::cout << sizeof(engine);
std::cout << '\t' << seed;
}
^ This method is way more efficient (x320 times) than serializing through a stream,
or by creating a dummy ostream and specializing std::operator<< for every case.
template<class T, T... v>
using LCG = std::linear_congruential_engine<T, v...>;
#define DummyRandSpec32 uint_fast32_t, 0xDEADBEEF, 0xCAFE, 0xFFFFFFFF
typedef LCG<DummyRandSpec32> DummyRand32; // the same engine type
template<class T, class R>
T* getSeed(R& rand) // getSeed 70:1 nextInt
{ // creating stream is heavy operation
// return rand._M_x; // cannot access private
__dummy_ostream<T> dumdum; // workaround
auto& didey = *reinterpret_cast<DummyRand32*>(&rand);
std::operator<<(dumdum, didey); // specialized
return dumdum.retrieve(); // pointer to state
}
int main() {
std::minstd_rand engine(19937);
std::cout << *getSeed<uint_fast32_t>(engine);
std::cout << std::endl << engine << std::endl;
}
^ Here is ill-coded my first attempt at a solution, if you want to compare.
It is worth mentioning that a field name of the state is implementation-specific.
Purposefully left out std::operator<< and __dummy_ostream.

Moving between two different contiguous containers

I have a std::vector<double> that I have to move to a boost::container::flat_set<double>.
Both containers are contiguous, so after sorting the vector in principle I could move the data from one to the other.
Is there a way to move the whole data between these two different containers?
Please, take into account that I want to move the whole data, not element by element.
I can move data between containers of the same type, but not between different containers.
std::vector<double> v1 = ...
std::sort(v1.begin(), v1.end());
std::vector<double> v2(std::move(v1)); // ok
boost::flat_set<double> f2(v1.begin(), v1.end()); // doesn't move, it copies
boost::flat_set<double> f3(std::move(v1)); // doesn't compile
It seems that for this to work flat_set should have a move constructor from containers with .data(), where the pointer is stolen from the argument.
I believe there is some way to verify whenever data alignment in both containers match and memcpy could be used (and source cleared without destructing) exists and maybe someone will share it with us, but as long as we want to use STL there is a way: the std::move_iterator. It makes your container constructor move elements instead of copying. It does not remove elements out of source container though, but leaves them stateless (e.g. empty strings as in example).
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <boost/container/flat_set.hpp>
int main()
{
std::vector<std::string> v1 = {"a","v","d"};
std::sort(v1.begin(), v1.end());
std::vector<std::string> v2(std::move(v1)); // ok
boost::container::flat_set<std::string> f1(std::make_move_iterator(v2.begin()), std::make_move_iterator(v2.end())); // moves, but does not remove elements from of source container
for(auto& s : v1)
std::cout << "'" << s << "'" << ' ';
std::cout << " <- v1 \n";
for(auto& s : v2)
std::cout << "'" << s << "'" << ' ';
std::cout << " <- v2 \n";
for(auto& s : f1)
std::cout << "'" << s << "'" << ' ';
std::cout << " <- f1 \n";
}
Output
<- v1
'' '' '' <- v2
'a' 'd' 'v' <- f1
Online code: https://wandbox.org/permlink/ZLbocXKdqYHT0zYi
It looks like it is not possible without modifying the constructor boost::container::flat.
Without modifying either class it seems that the only a hack would do it, for example using reinterpret_cast.
The solution I found is either to use an alternative implementation of vector or very ugly code.
Before going into my solution, I must that say that this is probably a
defect of both classes. These clases should have a set of
release()/aquire(start, end) functions that respectively
returns the pointer range to the data releasing the ownership and
gets the pointer range owning it from then on. An alternative could be to
have a constructor that moves from any other container that has a the
data member function.
Solution using reinterpret_cast and a different implementation of vector
It turns out that reinterpret_casting from std::vector to boost::container::flat_set is not possible, because the layout is not compatible.
However it is possible to reinterpret_cast from boost::container::vector to boost::container::flat_set out of the box (that is because they have a common implementation).
#include<cassert>
#include<boost/container/flat_set.hpp>
int main(){
boost::container::vector<double> v = {1.,2.,3.};
boost::container::flat_set<double> fs = std::move(reinterpret_cast<boost::container::flat_set<double>&>(v));
assert(v.size() == 0);
assert(*fs.find(2.) == 2.);s
assert(fs.find(4.) == fs.end());
}
So, I can replace std::vector by boost::container::vector and I can move data to a flat_set.
Non-portable solution using std::vector and ugly code
The reason the layout of std::vector and boost::container::vector are different is that boost::container::vector stores metadata in this way:
class boost::container::vector{
pointer m_start;
size_type m_size;
size_type m_capacity;
}
while std::vector (in GCC) is basically pure pointers,
class std::vector{
pointer _M_start;
pointer _M_finish;
pointer _M_end_of_storage;
}
So, my conclusion is that moving is possible only through a hack given that the implementation I use of std::vector is not compatible with boost::container::flat_set.
In an extreme case, one can do this (sorry if this code offends someone, the code is not portable):
template<class T>
boost::container::flat_set<T> to_flat_set(std::vector<T>&& from){
// struct dummy_vector{T* start; T* finish; T* end_storarge;}&
// dfrom = reinterpret_cast<dummy_vector&>(from);
boost::container::flat_set<T> ret;
struct dummy_flat_set{T* start; std::size_t size; std::size_t capacity;}&
dret = reinterpret_cast<dummy_flat_set&>(ret);
dret = {from.data(), from.size(), from.capacity()};
// dfrom.start = dfrom.finish = dfrom.end_storarge = nullptr;
new (&from) std::vector<T>();
return ret;
};
int main(){
std::vector<double> v = {1.,2.,3.};
boost::container::flat_set<double> fs = to_flat_set(std::move(v));
assert(v.size() == 0);
assert(*fs.find(2.) == 2.);
assert(fs.find(4.) == fs.end());
}
Note that I am not taking into account allocator issues at all. I am not sure how to handle allocators here.
In retrospect I don't mind using a form of cast for this specific problem, because somehow I have to tell that the vector is sorted before moving to flat_set. (The problem is that this goes to extreme because it is a reinterpret_cast.)
However this is a secondary issue, there should be legal way to move from std::vector to boost::container::vector.

Directly assigning to a std::vector after reserving does not throw error but does not increase vector size

Let's create a helper class to assist visualizing the issue:
class C
{
int ID = 0;
public:
C(const int newID)
{
ID = newID;
}
int getID()
{
return ID;
}
};
Suppose you create an empty std::vector<C> and then reserve it to hold 10 elements:
std::vector<C> pack;
pack.reserve(10);
printf("pack has %i\n", pack.size()); //will print '0'
Now, you assign a new instance of C into index 4 of the vector:
pack[4] = C(57);
printf("%i\n", pack[4].getID()); //will print '57'
printf("pack has %i\n", pack.size()); //will still print '0'
I found two things to be weird here:
1) shouldn't the assignment make the compiler (Visual Studio 2015, Release Mode) throw an error even in Release mode?
2) since it does not and the element is in fact stored in position 4, shouldn't the vector then have size = 1 instead of zero?
Undefined behavior is still undefined. If we make this a vector of objects, you would see the unexpected behavior more clearly.
#include <iostream>
#include <vector>
struct Foo {
int data_ = 3;
};
int main() {
std::vector<Foo> foos;
foos.reserve(10);
std::cout << foos[4].data_; // This probably doesn't output 3.
}
Here, we can see that because we haven't actually allocated the object yet, the constructor hasn't run.
Another example, since you're using space that the vector hasn't actually started allocating to you, if the vector needed to reallocate it's backing memory, the value that you wrote wouldn't be copied.
#include <iostream>
#include <vector>
int main() {
std::vector<int> foos;
foos.reserve(10);
foos[4] = 100;
foos.reserve(10000000);
std::cout << foos[4]; // Probably doesn't print 100.
}
Short answers:
1) There is no reason to throw an exception since operator[] is not supposed to verify the position you have passed. It might do so in Debug mode, but for sure not in Release (otherwise performance would suffer). In Release mode compiler trusts you that code you provide is error-proof and does everything to make your code fast.
Returns a reference to the element at specified location pos. No
bounds checking is performed.
http://en.cppreference.com/w/cpp/container/vector/operator_at
2) You simply accessed memory you don't own yet (reserve is not resize), anything you do on it is undefined behavior. But, you have never added an element into vector and it has no idea you even modified its buffer. And as #Bill have shown, the vector is allowed to change its buffer without copying your local change.
EDIT:
Also, you can get exception due to boundary checking if you use vector::at function.
That is: pack.at(4) = C(57); throws exception
Example:
https://ideone.com/sXnPzT

Which library to link for boost::hash_combine

I want to use boost::hash_combine in my project. However, I was unable to find the boost library that contains this function (the library libboost_functional does not exist). I am running Arch. Is it possible that I do not have all libraries installed?
Edit:
As sehe pointed out, including the right header was the key.
#include <iostream>
#include <boost/functional/hash.hpp>
int main() {
int x = 100;
int y = 10;
size_t h = 0;
boost::hash_combine(h, x);
boost::hash_combine(h, y);
std::cout << h << std::endl;
}
Luke 24:5:
“Why do you look for the living among the dead?"
Most of boost is header-only. There's nothing to link. In the case of hash-combine, everything is templates so there's nothing that could be hidden from the header file.

std::string::assign vs std::string::operator=

I coded in Borland C++ ages ago, and now I'm trying to understand the "new"(to me) C+11 (I know, we're in 2015, there's a c+14 ... but I'm working on an C++11 project)
Now I have several ways to assign a value to a string.
#include <iostream>
#include <string>
int main ()
{
std::string test1;
std::string test2;
test1 = "Hello World";
test2.assign("Hello again");
std::cout << test1 << std::endl << test2;
return 0;
}
They both work. I learned from http://www.cplusplus.com/reference/string/string/assign/ that there are another ways to use assign . But for simple string assignment, which one is better? I have to fill 100+ structs with 8 std:string each, and I'm looking for the fastest mechanism (I don't care about memory, unless there's a big difference)
Both are equally fast, but = "..." is clearer.
If you really want fast though, use assign and specify the size:
test2.assign("Hello again", sizeof("Hello again") - 1); // don't copy the null terminator!
// or
test2.assign("Hello again", 11);
That way, only one allocation is needed. (You could also .reserve() enough memory beforehand to get the same effect.)
I tried benchmarking both the ways.
static void string_assign_method(benchmark::State& state) {
std::string str;
std::string base="123456789";
// Code inside this loop is measured repeatedly
for (auto _ : state) {
str.assign(base, 9);
}
}
// Register the function as a benchmark
BENCHMARK(string_assign_method);
static void string_assign_operator(benchmark::State& state) {
std::string str;
std::string base="123456789";
// Code before the loop is not measured
for (auto _ : state) {
str = base;
}
}
BENCHMARK(string_assign_operator);
Here is the graphical comparitive solution. It seems like both the methods are equally faster. The assignment operator has better results.
Use string::assign only if a specific position from the base string has to be assigned.

Resources