I was creating a vector of my bitpacked vectors, called xor_funcs, using the length and value constructor for vector.
This is the test that failed:
TEST(vectorInit, size3) {
const xor_func temp{false, {0,0,0}};
vector<xor_func> arr{3, temp};
for(xor_func& f : arr) {
EXPECT_EQ(3, f.size()) << f;
}
for(int i = 0; i < 3; i++) {
ASSERT_EQ(3, arr[i].size()) << "for i=" << i;
arr[i].set(i);
}
}
It seems that the size() call is accessing uninitialized memory, for vectors of length 3 or more, but not ones of size 2. Valgrind confirms that the memory is not recently stack'd, malloc'd or free'd.
The xor_func is defined as such:
class xor_func {
private:
boost::dynamic_bitset<> bitset;
bool negated;
public:
xor_func(const bool neg, const std::initializer_list<int> lst);
// That's defined in cpp
xor_func(const size_t size) : bitset(size), negated(false) {}
// Disallow the trivial constructor, since I don't want
// any 0 length xor_funcs existing by default.
// xor_func() : bitset(), negated(false) {}
xor_func(const bool negated, const boost::dynamic_bitset<> bitset)
: bitset(bitset), negated(negated) {}
// That's all the constructors.
// Snip
}
I didn't do anything with the default copy and move constructors.
What is going on, and why does my test fail?
As dyb said, vector<xor_func> arr{3, temp}; was being interpreted as
vector<xor_func> arr({xor_func{3}, temp}), as the 3 could be converted into a xor_func by a constructor implicitly, and then it could choose the initializer list version of the constructor to call.
If you look at Is C++11 Uniform Initialization a replacement for the old style syntax?, you can see that one of the downsides of uniform initialization syntax is exactly this bug. A more trivial example is
// std::string constructor prototype for reference
// fill (6)
string (size_t n, char c);
void main() {
string myString{65, 'B'};
cout << myString << endl;
}
This will print out "AB", instead of "BBBBBB...BBB", as it can convert 65 to 'A', and then it's as if we wrote myString{'A', 'B'}. To fix it, simply don't try and use the uniform initialization syntax for this call and replace it with
string myString(65, 'B');
Another way I could fix this bug is to change the constructor xor_func(const size_t size) to be explicit xor_func(const size_t size), which prevents the compiler from implicitly converting the 3 to an xor_func.
Oh, there's another great answer What does the explicit keyword mean in C++.
Related
#include<iostream>
using namespace std;
template<class T>
class vee
{
T* v;
int size;
public:
vee(int m)
{
v = new T[size=m];
cout<<size<<"\n";
}
vee(T* a)
{
cout<<size<<"\n";
for(int i=0;i<size;i++)
{
v[i]=a[i];
}
}
};
int main()
{
int x[]={1,2,3};
int y[]={2,3,4};
vee<int> v1(3);
v1=x;
return 0;
}
Why i am getting 2 different values of "size" ?
I have created a constructor to intilize the parameter size and it shows correct value in first constructor but it throws a garbage value in the second constructor ,why??
Why i am getting 2 different values of "size" ?
vee(T* a) is called converting constructor. When you write something like v1=x;, array x decays to a pointer, then it is converted to vee with provided converting constructor.
v1=x; is as if you wrote v1=vee<int>(x);
As you can see a temporary instance is created with undefined size and pointer, which is bad. Then you assign this instance to v1 which is worse.
If you do not want this autoconversion in the future, declare your constructor explicit
explicit vee(T* a)
When doing v1=x, you actually go and create new object, since you have not overrided the '=' operator.
but it throws a garbage value in the second constructor ,why??
vee(int m)
{
v = new T[size=m]; // in this constructor you set size
cout<<size<<"\n";
}
vee(T* a)
{
// but in this constructor you don't set size
cout<<size<<"\n";
for(int i=0;i<size;i++)
{
v[i]=a[i];
}
}
So, when you create a vee using the second constructor - and read from size - your program has undefined behaviour.
I was trying a random code to accept values using dynamic size. Surprisingly the for loop in the Accept function does not execute. Instead, the control directly leaves the function. Please explain what is the mistake here?
using namespace std;
#include<iostream>
class consequtive
{
public : int *ptr;
int size;
public :
consequtive(int size);
void Accept();
};
consequtive::consequtive(int size)
{
ptr = new int[size];
}
void consequtive :: Accept()
{
cout<<"Enter elements :: "<<endl;
for(int i = 0 ; i < size ; i++)
{
cin>>ptr[i];
}
}
int main()
{
int size = 0;
cout<<"Enter size ::";
cin>>size;
consequtive obj(size);
obj.Accept();
}
A few problems here.
You have a class parameter that has the same name as a member, which isn't really a problem, but is a source of confusion (As in your case).
You never set the member size to anything inside the constructor.
For number one, I would recommend renaming the class member size to size_ or something similar, since this creates a separation and makes the variables easier to distinguish from each other. As for as the second problem, I would change your constructor to the following:
consequtive::consequtive(int size) : size_(size) // Assuming the member is called `size_`
{
ptr = new int[size];
}
The code should work now, and uses a concept called member initializer lists. Not setting the variable size results in undefined behavior.
You forgot to initialize the size member variable.
You could do something like this:
consequtive::consequtive(int size)
: size(size),
ptr(new int[size])
{
}
You should also add a destructor to your class, to avoid a memory leak:
consequtive::~consequtive()
{
delete[] ptr;
}
This size in the class definition
public : int *ptr;
int size;
this size in the constructor implementation
consequtive::consequtive(int size)
and this size in the main function
int size = 0;
are all different variables. The latter two will both have the same value because of the way they are used, but one size can be changed to a different value without the other being aware. The bug in the asker's code is because the first size is never given a value and is used uninitialized.
Solution:
consequtive::consequtive(int size): ptr(new int [size]), size(size)
{
}
Here we are using the Member Initializer List. We don't gain much from its use in this case, but it is a very useful tool. More on that here: Why should I prefer to use member initialization list?
Be cautious when using a parameter or local variable with the same name as a member. The inner most identifier always wins so inside
consequtive::consequtive(int size): ptr(new int [size]), size(size)
{
// in here
}
the size variable is the parameter and not the member. You can this->size to explicitly state you want the member, but it is a better idea to not reuse the identifier at all. You could forget to prepend this-> and the compiler is unlikely to warn you of the mistake.
I want to create a vector with diferent object of type A but ...
This code throws this exception:
free(): invalid pointer: 0x0000000000401757 ***
#include <vector>
class A
{
char * elem;
public:
A()
{
elem = new char[10];
}
void setA(char* name)
{
elem = name;
}
~A()
{
delete[] elem;
}
};
int main(int argc, char **argv)
{
std::vector<A> v_a;
for (int i = 0; i < 10; ++i)
{
A m_a;
m_a.setA("jaja");
v_a.push_back(m_a);
}
}
Why this is happening?? How can implement a correct solution?
When calling setA(...) you are not copying the data of the string, instead you are copying the address of a local string. (Check what cplusplus.com says about pointers and string literals)
After the block with the setA(...) call ends, this string goes out of scope so it's address is invalid afterwards
So you are trying to free memory from the heap in your destructor which was allocated on the stack and is long gone at this time...
Updated suggestion 1: added on Jan 27th, 2016
additionally take into account the need of a copy ctor when pushing instances of A to a std::vector. Obeying the Rule of three I added a copy assignment operator as well.
See also Rule of five in case of c++11
properly take care of possibly 'wrong' sized strings
#include <cstring>
...
/// copy ctor
A(const A& other) :
elem(new char[10])
{
// prevent duplicate code
setA(other.elem);
}
/// copy assignment operator
A& operator=(const A& other)
{
// prevent duplicate code
setA(other.elem);
return *this;
}
/// set A's name (which is truncated to 9 characters if necessary)
void setA(const char* name)
{
// copy first 9 chars from name
// if there's fewer chars: elem is padded with zeros
std::strncpy(elem, name, 9);
// add null character / zero (string delimiter) manually
// this is necessary for cases where name has 10 or more chars
elem[9] = 0;
}
(Obsolete) suggestion 1: continue working with c style strings
explicitly copy the passed string's data (you need to do this in order to make the method work)
add a length indicator to the parameter list of setA(...) (this is optional, you could also figure out the length of the string inside of the method...)
#include <cstring>
...
void setA(char* name, size_t length)
{
std::memcpy(elem, name, length);
}
Suggestion 2: switch to c++ style strings
use std::string (I'd prefer this version as it spares you the memory handling and reads very intuitively)
#include <string>
class A
{
std::string elem;
public:
A(){}
void setA(std::string name)
{
elem = name;
}
~A(){}
};
You modify the value of elem, which is a pointer to a memory area allocated on the free store. Now, elem points to a string literal, which is not applicable to delete or delete[].
deleteing objects not on the free store is undefined behavior. Your destructor attempts it nevertheless.
How would I go about allocating an array of a class without constructing the class, so I could fill up the array later?
I was originally trying to use
Myclass * array = new Myclass[N];
But it tries to construct Myclass to N.
First just declare it without allocating
Myclass * array[N];
when you need it
for(int i=0;i<N;i++){
array[i] = new Myclass(/*params*/);
}
But consider using std::vector/std::list if you must not have to manage memory yourself.
If you really want to do that, (not sure why), you could try
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass()
{ cout << "helo" << endl; }
};
int main(int argc, char *argv[])
{
int size = 4;
// Here is the trick, pointer to pointer.
MyClass **vec = new MyClass *[size];
cout << "before" << endl;
for (int i = 0; i < 4; ++i)
vec[i] = new MyClass;
// remember to free the vec
return 0;
}
Someone suggested placement new, so here it goes:
// allocate space
std::vector<unsigned char> mybuffer(N * sizeof(Myclass));
Myclass *array = reinterpret_cast<Myclass *>(&mybuffer[0]);
// when you're ready to use it
new( &array[0] ) Myclass(2);
new( &array[1] ) Myclass(3);
// etc...
// when you're done with it
array[0].~Myclass();
array[1].~Myclass();
// etc....
Of course, it is undefined behaviour to use array[x] before you have new'd it, or after you called the destructor.
This is generally something you wouldn't use as a solution to a "normal" problem. Consider actually defining a default constructor that does nothing, and having a function you call later which enhances the objects above their default state.
If you can use C++11, the optimal solution for you is probably std::vector<MyClass> with emplace-base insertions:
class MyClass {
public:
MyClass(int a, bool b, char c); // some non-default constructor
MyClass(double d); // another constructor
void bar();
};
void foo(int n) {
std::vector<MyClass> mv;
mv.reserve(n); // not even needed but beneficial if you know the final size.
// emplace_back uses perfect forwarding to call any arbitrary constructor:
mv.emplace_back(2, false, 'a');
mv.emplace_back(3, true, 'b');
mv.emplace_back(3.1415926535);
// can iterate vector easily:
for (auto &i : mv) {
i.bar();
}
// everything destructed automatically when the collection falls of scope ...
}
This creates the values in the collection directly without a copy and defers any construction of elements until you are ready, unlike new[], which makes a bunch of default objects at array-creation time. It is generally better than placement new as well, since it doesn't leave open opportunities for missed destruction or destructing an invalid memory location as well as being just easier to read.
Alternatively, you may use boost::optional.
So in your case:
std::vector<boost::optional<Myclass>> array(N);
I want to store a dynamic array of structs as a member variable within another struct. Is this the proper way to use the constructor given my example in main?
EDIT
I corrected some of the obvious mistakes I had in the code (was 6am at the time). I also added another member to B to see if the push_back is still correct. I know my life would be a lot easier using vectors for dynamic memory but I need to do it this way as these are structs to be used with thrust::device_vector in the end.
struct A
{
float mem1;
int mem2;
};
struct B
{
A * Aarr1;
A * Aarr2;
B(A * a1, A * a2): Aarr1(a1), Aarr2(a2){}
};
int main()
{
A * test = new A[5];
A * test2 = new A[10];
vector<B> btest;
btest.push_back(B(test, test2));
for(int i=0; i<5; i++)
printf("mem1: %f, mem2: %i \n", btest[0].Aarr[i].mem1, btest[0].Aarr[i].mem2);
}
Taken in isolation, the constructor is fine. However, there are many other problems with the code.
As it stands, your code is leaking memory since the array is never deallocated.
You might want to consider moving away from using C arrays to std::vector or std::array.
There's also a bug in printf() (misspelt as print()): one of the two mem1 should be mem2.
The constructor of B is OK, but the way you invoke push_back() is not:
btest.push_back(B(A));
You should do this:
btest.push_back(B(test));
Moreover, the explicit construction of a B object is not necessary, since your constructor is not marked as explicit:
btest.push_back(test);
Also consider using automatic memory management rather than raw pointers (std::vector<> instead of arrays, smart pointers instead of pointers). This way, you will avoid leaking memory due to forgetting this:
delete test;
Leaking aside, the worst thing is that your code also has Undefined Behavior, because it uses the value of uninitialized variables (the member variables of A within the for loop).
Finally, you shouldn't use : after class names in a class definition. This is how you could rewrite your code in C++11:
#include <vector>
#include <cstdio>
struct A // Do not use ":" here, that's for introducing inheritance,
// which you are not using in your example.
{
float mem1 = 0.0; // In C++11, you can specify default initialization
int mem2 = 0; // for your member variables this way. In C++03 you
// would have to define a default constructor which
// initializes your member variables to the desired
// value.
};
struct B
{
std::vector<A> Aarr;
// ^^^^^^^^^^^^^^
// Prefer using standard containers over dynamically allocated arrays, as
// it saves your from taking care of memory management and avoids leaks.
explicit B(size_t s): Aarr(s) { }
// ^^^^^^^^
// It is usually a good idea to mark constructors which take on argument
// and are not copy constructors as explicit, to avoid awkward implicit
// conversions.
};
int main()
{
std::vector<B> btest;
btest.push_back(B(5));
// ^^^^
// We need to explicitly construct an object of type B,
// because we have marked B's constructor as explicit.
for(int i=0; i<5; i++)
{
std::printf(
"mem1: %f, mem2: %i \n",
btest[0].Aarr[i].mem1,
btest[0].Aarr[i].mem2
// ^
// You had "mem1" here.
);
}
}
There are few minor mistakes and typos in your code. It should look like this:
struct A // <-- no ':' after name type
{
float mem1;
int mem2;
};
struct B // <-- no ':' after name type
{
A * Aarr;
B(A * a): Aarr(a){}
};
int main()
{
A * test = new A[5];
vector<B> btest;
btest.push_back(B(test)); // <-- test, A is name of type
for(int i=0; i<5; i++)
printf("mem1: %f, mem2: %i \n", // <-- printf, not print
btest[0].Aarr[i].mem1, btest[0].Aarr[i].mem1);
}
Also consider using std::vector or std::array instead of C-style arrays as well.