I'm debugging a simple C++ script using gdb and see that I get an error when I try and initialize temp_grid. I try and compile it by running
g++ -Wall initial.cc -o initial
Is there a way to avoid this segmentation fault with something inside the script?
#include <iostream>
#include <array>
#include <valarray>
#include <stdlib.h>
#include <memory>
using namespace std;
int main()
{
using std::array;
array<array<float, 1024>, 1024> grid ={};
// temp grid
array<array<float, 1024>, 1024> temp_grid ={};
return 0;
}
You are most likely overflowing the stack, which has relatively limited storage space for local variables. Try allocating them using dynamic storage (using new). For maximum robustness, use smart pointers (unique_ptr) to manage the pointers.
Related
I have an array in host, and I want to transfer it to device with a different order.
I have tried this toy code complied with nvc++ test.cpp -stdpar
$ cat test.cpp
#include <iostream>
#include <thrust/iterator/permutation_iterator.h>
#include <thrust/copy.h>
#include <thrust/sequence.h>
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <array>
using Real = float;
int main(int argc, char* argv[]) {
std::array<std::size_t,6> idx{0,1,2,3,5,4};
thrust::host_vector<Real> hvec(6);
thrust::sequence(hvec.begin(),hvec.end());
typedef thrust::host_vector<Real>::iterator EleItor;
typedef std::array<std::size_t,6>::iterator IdxItor;
thrust::permutation_iterator<EleItor,IdxItor> itor(hvec.begin(),idx.begin());
thrust::device_vector<Real> test;
thrust::copy(itor,itor+6,test); // error
thrust::copy(itor,itor+6,std::ostream_iterator<Real>(std::cout," ");
}
The problem is that thrust::copy does not allow copy from host to device, how can I bypass this restriction?
According to the documentation is is possible to use thrust::copy to copy from host to device, but you need to pass the device iterator:
//-----------------------------vvvvvvvv--
thrust::copy(itor, itor+6, test.begin());
Note that before that you need to allocate memory for the device vector.
Fortunately the thrust::device_vector has a constructor taking a size that will allocate the required memory.
You can use something like:
thrust::device_vector<Real> test(host_vector.size());
Edit (credit goes to #paleonix):
There is another constructor taking iterators, i.e. one can do both allocation and copy as initialization in one line which also has the advantage of avoiding the unnecessary initialization of the memory to 0.0f.
thrust::device_vector<Real> test(itor, itor+6);
What are the right methods?
How to avoid the 3 errors?
I tried the followings:
#include <vector>
#include <array>
#include <iostream>
using namespace std;
struct s_4{double x,z,k,wsize;};
typedef vec4 vector <array<double,4>>; //ERROR #1
void main()
{
vector <s_4> s1;
vector <array<double,4>> d1;
s1.push_back(*new (s_4){10.0,11,1,0.25e-3}); //OK
d1.push_back(*new (array<double,4>){10.0,11,1,0.25e-3}); //OK
d1.push_back(*new (double[4]){10.0,11,1,0.25e-3}); //ERROR #2
vector <array<double,4>> d2{11,12,13,14.1}; //ERROR #3
getchar();
}
It is like it is very difficult to use large arrays in vectors
The correct code is:
#include <vector>
#include <array>
#include <iostream>
using namespace std;
struct s_4{double x,z,k,wsize;};
typedef vector <array<double,4>> vec4;
int main()
{
vector <s_4> s1;
vector <array<double,4>> d1;
s1.push_back({10.0,11,1,0.25e-3});
d1.push_back({10.0,11,1,0.25e-3});
d1.push_back({10.0,11,1,0.25e-3});
vector <array<double,4>> d2{{11,12,13,14.1}};
return 0;
}
Your first error in the typedef is that the name of the typedef comes last.
Your first three push_backs were leaking memory, you don't need to name the type when initialising.
The second error is because a c array can't be converted directly to a std::array.
The last needs two sets of braces, one to initialise the vector and one to initialise each array.
In addition to Alan's answer:
Why are you trying to allocate your arrays on the heap? You could place your arrays on the stack and use initializer lists:
#include <vector>
#include <array>
#include <iostream>
int main()
{
std::vector <std::array<double,4>> data = {
{10.0,11,1,0.25e-3},
{10.0,11,1,0.25e-3},
{10.0,11,1,0.25e-3},
{11,12,13,14.1}
};
}
However, initializer lists are a C++11 feature so you may compile with -std=c++11:
g++ -g -Wall -O2 -std=c++11 test.cpp -o test
Furthermore you should avoid using namespace std, as this may cause problems if you use additional libraries that implement for example vectors for mathematical calculations.
Like this question already asked, I'd like to initialize a container using STL where the elements are hard-coded in the cleanest manner possible. In this case, the elements are a doubly nested container:
set<vector<int> > A;
And I'd like (for example) to put the following values in:
A = [[0,0,1],[0,1,0],[1,0,0],[0,0,0]];
C++0x fine, using g++ 4.4.1. STL is preferable as I don't use Boost for any other parts of the code (though I wouldn't mind an example with it!).
This does use g++ 4.4.1, with -std=c++0x
#include <set>
#include <vector>
using namespace std;
int main()
{
set<vector<int>> A = {{0,0,1},{0,1,0},{1,0,0},{0,0,0}};
}
#include <boost/assign/list_of.hpp>
#include <vector>
#include <set>
using namespace std;
using namespace boost::assign;
int main()
{
set<vector<int> > A;
A = list_of
(list_of(0)(0)(1))
(list_of(0)(1)(0))
(list_of(1)(0)(0));
(list_of(0)(0)(0));
return 0;
}
I am trying to pass data around the numpy and boost::ublas layers. I
have written an ultra thin wrapper because swig cannot parse ublas'
header correctly. The code is shown below
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/lexical_cast.hpp>
#include <algorithm>
#include <sstream>
#include <string>
using std::copy;
using namespace boost;
typedef boost::numeric::ublas::matrix<double> dm;
typedef boost::numeric::ublas::vector<double> dv;
class dvector : public dv{
public:
dvector(const int rhs):dv(rhs){;};
dvector();
dvector(const int size, double* ptr):dv(size){
copy(ptr, ptr+sizeof(double)*size, &(dv::data()[0]));
}
~dvector(){}
};
with the SWIG interface that looks something like
%apply(int DIM1, double* INPLACE_ARRAY1) {(const int size, double* ptr)}
class dvector{
public:
dvector(const int rhs);
dvector();
dvector(const int size, double* ptr);
%newobject toString;
char* toString();
~dvector();
};
I have compiled them successfully via gcc 4.3 and vc++9.0. However
when I simply run
a = dvector(array([1.,2.,3.]))
it gives me a segfault. This is the first time I use swigh with numpy
and not have fully understanding between the data conversion and
memory buffer passing. Does anyone see something obvious I have
missed? I have tried to trace through with a debugger but it crashed within the assmeblys of python.exe. I have no clue if this is a swig problem or of my simple wrapper. Anything is appreciated.
You may be interested in looking at the pyublas module. It does the conversion between numpy arrays and ublas data types seamlessly and without copying.
You may want to replace
copy(ptr, ptr+sizeof(double)*size, &(dv::data()[0]));
by
copy(ptr, ptr+size, &(dv::data()[0]));
Remember that in C/C++ adding or subtracting from a pointer moves it by a multiple of the size of the datatype it points to.
Best,
Working on a WinPCap project. Trying to do some basic pointer and memory operations and having lots of errors.
I've included the two lines I'm trying to run along with the includes.
The same lines in another VSC++ project work just fine. This is the error I am getting
Unhandled exception at 0x75a79617 in
pktdump_ex.exe: Microsoft C++
exception: std::bad_alloc at memory
location 0x0012f8e4..
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include "DataTypes.h"
#include <sstream>
#include "EthernetLayer.h"
#include <pcap.h>
int* testPointer = new int[2];
delete[] testPointer;
EDIT:
Found out something useful.
The following code snippet is what is crashing the winpcap library.
EthernetStructPointers* testData;
testData = (EthernetStructPointers*)pkt_data;
EthernetStruct newData;
memcpy(newData.DEST_ADDRESS, testData->DEST_ADDRESS, 6);
These are the definitions of the structs.
struct EthernetStructPointers
{
u_char DEST_ADDRESS[6];
u_char SOURCE_ADDRESS[6];
u_char TYPE[2];
};
struct EthernetStruct
{
u_char DEST_ADDRESS[6];
u_char SOURCE_ADDRESS[6];
u_char TYPE[2];
u_char* dataPointer;
string DestAddress;
string SourceAddress;
string Type;
int length;
};
My guess is the freestore is corrupted by one the previous statements (perhaps by an incorrect use of the pcap interface), and you only learn of the error on the next memory allocation or release, when the manager detects it and throws a bad alloc.
std::bad_alloc should be thrown when you try to new something and have run out of memory. Can you check how much free memory is available to your process?