dynamical initialization of std::vector<unique_ptr<class T>> - c++11

I have a class Grid declared as follows:
Grid.h
#ifndef DATATEST_GRID_H
#define DATATEST_GRID_H
#include <memory>
#include <vector>
#include "Position.h"
class Grid
{
public:
Grid(int length_x, int length_y);
~Grid();
Position *at(int x, int y);
void printGrid();
private:
int length_x, length_y;
std::vector<std::unique_ptr<Position>> grid;
};
#endif
Its most important member variable is the vector<unique_ptr<Position>>, which I'm using to simulate a 2-dimensional array whose size is determined at runtime. The class declaration for the Position is as follows:
Position.h
#ifndef DATATEST_POSITION_H
#define DATATEST_POSITION_H
#include <memory>
#include <string>
class Position {
public:
Position(int x, int y);
~Position();
std::string toString();
int getX() { return x; };
int getY() { return y; };
private:
int x, y;
};
#endif
In the Grid's constructor, I want to create the desired number of Positions and add them to the vector<unique_ptr<Position>>.
Grid.cpp
#include "Grid.h"
#include <iostream>
#include <memory>
#include <vector>
#include "Position.h"
Grid::Grid(int length_x, int length_y)
: length_x(length_x), length_y(length_y)
{
grid.resize(length_x * length_y);
for (int x = 0; x < length_x; x++) {
for (int y = 0; y < length_y; y++) {
/* Option 1 */
std::unique_ptr<Position> temp = std::make_unique<Position>(x, y);
grid.push_back(std::move(temp));
/* Option 2 */
// std::unique_ptr<Position> temp = std::make_unique<Position>(x, y);
// grid.emplace_back(std::move(temp));
/* Option 3 */
// grid.push_back(std::make_unique<Position>(x, y));
/* Option 4 */
// grid.emplace_back(std::make_unique<Position>(x, y));
}
}
}
Grid::~Grid()
{
grid.clear();
}
Position *Grid::at(int x, int y)
{
if (x < 0 || x >= length_x || y < 0 || y >= length_y) {
return nullptr;
}
else {
return grid.at(x * (length_y) + y).get();
}
}
void Grid::printGrid()
{
for (int i = 0; i < grid.size(); i++) {
std::cout << grid.at(i)->toString() << std::endl;
}
}
I'm testing access by calling Position::toString for each unique_ptr<Position> and printing the result to the console.
Position.cpp
#include "Position.h"
#include <string>
Position::Position(int x, int y)
: x(x), y(y)
{
}
Position::~Position()
{
}
std::string Position::toString()
{
return "Position(" + std::to_string(x) + ", " + std::to_string(y) + ")";
}
And finally, the main function:
Main.cpp
#include "Grid.h"
#include "Position.h"
int main()
{
Grid g(2, 2);
g.printGrid();
return 0;
}
No matter which way I populate the vector<unique_ptr<Position>>, I always get the following error:
First-chance exception at 0x0087D8A3 in CombatSim.exe: 0xC0000005: Access violation reading location 0x00000000.
Unhandled exception at 0x0087D8A3 in CombatSim.exe: 0xC0000005: Access violation reading location 0x00000000.
As far as I know, I could have one of four problems:
1) I'm adding the unique_ptr to the created Position object to the vector incorrectly
2) I'm using the wrong method to dynamically create Position objects.
3) All of the above.
4) Something I don't know about.

Use std::vector::reserve(n) instead of std::vector::resize(n) if you are going to push_back those n elements afterwards.
resize will fill the vector with initialized objects, so the vector.size() will be n after that.
reserve will just reserve enough space for all n element, but will not insert any objects.

It seems that resizing the grid will first insert length_x * length_y unique pointers that all point to 0. Your push_back should be fine but your real elements start at position length_x * length_y in the vector. I think removing the line
grid.resize(length_x * length_y);
should solve the problem. Maybe someone else can explain why this happens.

Related

Get item closest to a value in a std::vector of doubles

Is there an elegant way in C++ 11 to get the item from a std::vector of doubles which is closest to a certain value?
Code:
#include <iostream>
#include <vector>
double GetClosest(const std::vector<double>& vec, double value) {
// How to get the item closest to "value" from the items in vec. Vec is assumed to be sorted.
}
int main() {
std::vector<double> my_doubles_vec;
my_doubles_vec.push_back(101480.76915103197);
my_doubles_vec.push_back(101480.85708367825);
my_doubles_vec.push_back(101480.93293087184);
my_doubles_vec.push_back(101481.0027936101);
my_doubles_vec.push_back(101481.5625);
my_doubles_vec.push_back(101481.5626);
std::cout.precision(17);
std::cout << GetClosest(my_doubles_vec, 101480.76915103201) << std::endl; // Should output "101480.76915103197"
std::cout << GetClosest(my_doubles_vec, 101480.93293086279) << std::endl; // Should output "101480.93293087184"
std::cout << GetClosest(my_doubles_vec, 101481.5625) << std::endl; // Should output "101481.5625"
return 0;
}
Since its a std::vector of doubles, I think precision comes into play? Or can the logic be made in such a way that one doesn't need to bother about precision?
You could use std::partition_point, std::lower_bound or std::upper_bound on the sorted range.
Example:
#include <algorithm>
#include <cmath>
#include <stdexcept>
double GetClosest(const std::vector<double>& vec, double value) {
if(vec.empty()) throw std::runtime_error("no elements");
// partition_point is the most generic of the three:
auto it = std::partition_point(vec.begin(), vec.end(), [value](double v) {
return v < value;
});
// or auto it = std::lower_bound(vec.begin(), vec.end(), value);
// or auto it = std::upper_bound(vec.begin(), vec.end(), value);
if(it == vec.end()) --it; // value larger than the largest in the vector
else if( it != vec.begin()) { // value not less than first
// check which one of the two around the partition point that is closest
if(std::abs(*std::prev(it) - value) < std::abs(*it - value)) --it;
}
return *it;
}
Since the vector is sorted, you could try something like this:
#include <algorithm>
#include <cmath>
#include <stdexcept>
double GetClosest(const std::vector<double>& vec, double value) {
if (vec.empty()) throw std::invalid_argument("vector cant be empty");
if (vec.size() == 1) return vec[0];
auto iter = std::find_if(vec.begin(), vec.end(),
[=](double d){ return d >= value; }
);
if (iter == vec.begin()) return vec.front();
if (iter == vec.end()) return vec.back();
if (std::abs(value - *(iter-1)) < std::abs(value - *iter)) --iter;
return *iter;
}

How to fix "segmentation fault (core dumped)" dependant on size

I created a class "config" that contains 12 bool values, organized in a std::array. The class has an "icing" function that returns a double value.
Trying to order a vector of 2^12 (4096) configs through a std:: sort (contained in #include ) using a predicate i have written, i get a segmentation fault error.
Shrinking the vector to 205 (not 1 more) eliminates the error, but I don't know why.
If i make the vector 4096 long, and try to sort only a little part, it works until the part is long 175+.
Shrinking the vector to for example around 1000, limits the partial sorting to around 20, before it gives the segmentation error.
#include <array>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
class config {
public:
config (){ //constructor, default
array<bool,12> t;
for (bool& b: t){
b=false;
}
val=t;
g=1;
}
config (const config& fro): val(fro.val){}; //copy constructor
array<bool,12> get_val(){ return val; } //returns the array
void set_tf(int n, bool tf){ val[n]=tf; } //sets a certain boolean in the array to false/true
void set_g(double d){ g=d; } //this sets the constant for calculation to a number
void print(){
cout<<"values: ";
for (auto b: val){ cout<<b<<" "; }
cout<<endl;
}
config & incr(int n=1){ //this increases the vector by 1 following the rules for binary numbers, but has the digits reversed
for(int j=0; j<n; j++){
int i=0;
bool out=false;
while(val[i]==true){
val[i]=false;
i++;
}
val[i]=true;
}
return *this;
}
double energy(){
int ct=0;
int cf=0;
for(auto b:val){ if(b==true){ ct++; } else { cf++; } }
return (abs(ct-cf));
}
double icing(){ //here is the "value" for ordering purposes
int n=0;
for(int i=0; i<11; i++){
if(val[i]!=val[i+1]){ n++; }
}
double temp=-g*n+this->energy();
return temp;
}
private:
array<bool,12> val;
double g;
};
bool pred (config c1, config c2){ return c1.icing()>c2.icing(); } //this sets the ordering predicate
template <typename T> //this orders the vector
void csort (vector <T>& in){
sort(in.begin(), in.end(), pred);
}
int main(){
vector<config> v;
for (int i=0; i<4096; i++){ //cicle that creates a vector of successive binaries
for(auto& c:v){
c.incr();
}
config t;
v.push_back(t);
}
sort(v.begin(), v.begin()+174, pred); //this gives seg.fault when 175+
csort(v); //this gives segmentation fault when the vec is 206 long or longer
}
I expected the code to order the vector, but it goes into segmentation fault.
Your program has undefined behaviour in sort function because your predicate takes config by value, so copies are made and in this place copy constructor is called which copies only array val, but not g.
bool pred (config c1, config c2){ return c1.icing()>c2.icing(); }
// takes by value, copy ctor is called
config (const config& fro): val(fro.val){}; // only val is copied, g HAS GARBAGE VALUE
// icing in pred uses g !! - stric weak ordering is violated because g has GARBAGE VALUE
Fix 1:
pass config by const config&:
bool pred (const config& c1, const config& c2){ return c1.icing()>c2.icing(); }
or fix 2:
g is initialized in copy constructor:
config (const config& fro): val(fro.val), g(fro.g){};

OpenCV and Mat::forEach operator not working in full image

I am trying to segment a depth image, so that values of depth between limits (low and high) remain the same, and values outside limits are set to 0.
To accomplish this I am trying to use the forEach method in OpenCV 3, to speed up the operation using all the available cores of the CPU.
Implementing the function this way, it works:
void Filter_Image(cv::Mat &img, int low, int high)
{
for (uint8_t &p : cv::Mat_<uint8_t>(img))
{
if(((p > low) && (p < high)) == false)
p = 0;
}
}
However, when I try to use the lambda expression, I only get correct results in one vertical third of the image (if you splitted the image in 3 columns, I only get the first left column well segmented). The code is as follows:
void Filter_Image(cv::Mat &img, int low, int high)
{
img.forEach<uint8_t>([&](uint8_t &p, const int * position) -> void {
if(((p > low) && (p < high)) == false)
p = 0;
});
}
The functions are called from this piece of code (simplified for testing):
#include "opencv/cv.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include "config_parser.h"
#include "background_substractor.h"
#include "object_tracker.h"
#include "roi_processing.h"
#include "filtering_functions.h"
using namespace cv;
int main(int argc, char **argv)
{
Mat opencv_frame;
namedWindow("Input Video");
//parse config
VIDEO_CONFIG videoConfig;
BACK_SUBS_CONFIG backSubsConfig;
TRACKER_CONFIG trackerConfig;
ROI_CONFIG roiConfig;
FILTERING_DATA filteringData;
Parse_Config("../Config/ConfigDepthImage.json", videoConfig, backSubsConfig, trackerConfig, filteringData, roiConfig);
Display_Config(videoConfig, backSubsConfig, trackerConfig, filteringData, roiConfig);
VideoCapture videoInput(videoConfig.path.c_str());
if (!videoInput.isOpened())
{
std::cout<<"Could not open reference video"<<std::endl;
return -1;
}
while (1)
{
videoInput >> opencv_frame;
if(opencv_frame.empty())
{
std::cout<<"Empty frame"<<std::endl;
destroyWindow("Input Video");
destroyWindow("Filtered Video");
break;
}
Filter_Image(opencv_frame, filteringData.min, filteringData.max);
//show video
imshow("Input Video", opencv_frame);
waitKey((1.0/videoConfig.fps)*1000);
}
return 0;
}
The difference in results can be observed in the displayed images:
This is the good one:
And this is the bad result in the same conditions using forEach:
I cannot see the error or the difference between the two functions. The type of the image is CV_8UC1.
Could anyone provide a clue?
Thank yo all very much in advance.

"Warning : Non-POD class type passed through ellipsis" for simple thrust program

In spite of reading many answers on the same kind of questions on SO I am not able to figure out solution in my case. I have written the following code to implement a thrust program. Program performs simple copy and display operation.
#include <stdio.h>
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
int main(void)
{
// H has storage for 4 integers
thrust::host_vector<int> H(4);
H[0] = 14;
H[1] = 20;
H[2] = 38;
H[3] = 46;
// H.size() returns the size of vector H
printf("\nSize of vector : %d",H.size());
printf("\nVector Contents : ");
for (int i = 0; i < H.size(); ++i) {
printf("\t%d",H[i]);
}
thrust::device_vector<int> D = H;
printf("\nDevice Vector Contents : ");
for (int i = 0; i < D.size(); i++) {
printf("%d",D[i]); //This is where I get the warning.
}
return 0;
}
Thrust implements certain operations to facilitate using elements of a device_vector in host code, but this apparently isn't one of them.
There are many approaches to addressing this issue. The following code demonstrates 3 possible approaches:
explicitly copy D[i] to a host variable, and thrust has an appropriate method defined for that.
copy the thrust device_vector back to a host_vector before print-out.
use thrust::copy to directly copy the elements of the device_vector to a stream.
Code:
#include <stdio.h>
#include <iostream>
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/copy.h>
int main(void)
{
// H has storage for 4 integers
thrust::host_vector<int> H(4);
H[0] = 14;
H[1] = 20;
H[2] = 38;
H[3] = 46;
// H.size() returns the size of vector H
printf("\nSize of vector : %d",H.size());
printf("\nVector Contents : ");
for (int i = 0; i < H.size(); ++i) {
printf("\t%d",H[i]);
}
thrust::device_vector<int> D = H;
printf("\nDevice Vector Contents : ");
//method 1
for (int i = 0; i < D.size(); i++) {
int q = D[i];
printf("\t%d",q);
}
printf("\n");
//method 2
thrust::host_vector<int> Hnew = D;
for (int i = 0; i < Hnew.size(); i++) {
printf("\t%d",Hnew[i]);
}
printf("\n");
//method 3
thrust::copy(D.begin(), D.end(), std::ostream_iterator<int>(std::cout, ","));
std::cout << std::endl;
return 0;
}
Note that for methods like these, thrust is generating various kinds of device-> host copy operations to facilitate the use of device_vector in host code. This has performance implications, so you might want to use the defined copy operations for large vectors.

Boost.Variant Vs Virtual Interface Performance

I'm trying to measure a performance difference between using Boost.Variant and using virtual interfaces. For example, suppose I want to increment different types of numbers uniformly, using Boost.Variant I would use a boost::variant over int and float and a static visitor which increments each one of them. Using class interfaces I would use a pure virtual class number and number_int and number_float classes which derive from it and implement an "increment" method.
From my testing, using interfaces is far faster than using Boost.Variant.
I ran the code at the bottom and received these results:
Virtual: 00:00:00.001028
Variant: 00:00:00.012081
Why do you suppose this difference is? I thought Boost.Variant would be a lot faster.
** Note: Usually Boost.Variant uses heap allocations to guarantee that the variant would always be non-empty. But I read on the Boost.Variant documentation that if boost::has_nothrow_copy is true then it doesn't use heap allocations which should make things significantly faster. For int and float boost::has_nothrow_copy is true.
Here is my code for measuring the two approaches against each other.
#include <iostream>
#include <boost/variant/variant.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/date_time/posix_time/ptime.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <boost/format.hpp>
const int iterations_count = 100000;
// a visitor that increments a variant by N
template <int N>
struct add : boost::static_visitor<> {
template <typename T>
void operator() (T& t) const {
t += N;
}
};
// a number interface
struct number {
virtual void increment() = 0;
};
// number interface implementation for all types
template <typename T>
struct number_ : number {
number_(T t = 0) : t(t) {}
virtual void increment() {
t += 1;
}
T t;
};
void use_virtual() {
number_<int> num_int;
number* num = &num_int;
for (int i = 0; i < iterations_count; i++) {
num->increment();
}
}
void use_variant() {
typedef boost::variant<int, float, double> number;
number num = 0;
for (int i = 0; i < iterations_count; i++) {
boost::apply_visitor(add<1>(), num);
}
}
int main() {
using namespace boost::posix_time;
ptime start, end;
time_duration d1, d2;
// virtual
start = microsec_clock::universal_time();
use_virtual();
end = microsec_clock::universal_time();
// store result
d1 = end - start;
// variant
start = microsec_clock::universal_time();
use_variant();
end = microsec_clock::universal_time();
// store result
d2 = end - start;
// output
std::cout <<
boost::format(
"Virtual: %1%\n"
"Variant: %2%\n"
) % d1 % d2;
}
For those interested, after I was a bit frustrated, I passed the option -O2 to the compiler and boost::variant was way faster than a virtual call.
Thanks
This is obvious that -O2 reduces the variant time, because that whole loop is optimized away. Change the implementation to return the accumulated result to the caller, so that the optimizer wouldn't remove the loop, and you'll get the real difference:
Output:
Virtual: 00:00:00.000120 = 10000000
Variant: 00:00:00.013483 = 10000000
#include <iostream>
#include <boost/variant/variant.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/date_time/posix_time/ptime.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <boost/format.hpp>
const int iterations_count = 100000000;
// a visitor that increments a variant by N
template <int N>
struct add : boost::static_visitor<> {
template <typename T>
void operator() (T& t) const {
t += N;
}
};
// a visitor that increments a variant by N
template <typename T, typename V>
T get(const V& v) {
struct getter : boost::static_visitor<T> {
T operator() (T t) const { return t; }
};
return boost::apply_visitor(getter(), v);
}
// a number interface
struct number {
virtual void increment() = 0;
};
// number interface implementation for all types
template <typename T>
struct number_ : number {
number_(T t = 0) : t(t) {}
virtual void increment() { t += 1; }
T t;
};
int use_virtual() {
number_<int> num_int;
number* num = &num_int;
for (int i = 0; i < iterations_count; i++) {
num->increment();
}
return num_int.t;
}
int use_variant() {
typedef boost::variant<int, float, double> number;
number num = 0;
for (int i = 0; i < iterations_count; i++) {
boost::apply_visitor(add<1>(), num);
}
return get<int>(num);
}
int main() {
using namespace boost::posix_time;
ptime start, end;
time_duration d1, d2;
// virtual
start = microsec_clock::universal_time();
int i1 = use_virtual();
end = microsec_clock::universal_time();
// store result
d1 = end - start;
// variant
start = microsec_clock::universal_time();
int i2 = use_variant();
end = microsec_clock::universal_time();
// store result
d2 = end - start;
// output
std::cout <<
boost::format(
"Virtual: %1% = %2%\n"
"Variant: %3% = %4%\n"
) % d1 % i1 % d2 % i2;
}

Resources