If I create a two class members of char* type and is array. And if I resize first member of the class it overwrite the second member with same values.
Why it happens?
Is it some memory management issues?
#include <iostream>
using namespace std;
class myclass
{
private:
const char *arr1[0];
const char *arr2[4] {
"one",
"two",
"three",
"four"
};
public:
void run() {
int f = 0;
*this->arr1 = new char[4];
for(f = 0; f < 4; f++) {
this->arr1[f] = "foo";
}
for(f = 0; f < 4; f++) {
cout << this->arr2[f] << endl;
}
}
};
int main()
{
myclass *my = new myclass();
my->run();
return 0;
}
Output
foo
foo
foo
foo
const char *arr1[0];
Zero-sized arrays are not allowed in standard C++. Your compiler is allowing it as an extension to the language.
Even if your compiler has this extension, dereferencing an array of size 0 causes undefined behavior and you are doing this here:
*this->arr1 = new char[4];
I don't know what your intention here is, either you want
const char *arr1[4];
in which case *this->arr1 = new char[4]; is unnecessary or you want
const char **arr1;
in which case it should be this->arr1 = new const char*[4];.
You should not use char* to manage strings, use std::string instead, which does the memory management for you. Similarly, for multiple strings use std::vector<std::string> instead of char**.
There doesn't seem any reason to use dynamic memory allocation in main either. The same way as you should use std::vector to manage dynamically-sized arrays of objects instead of using new[]/delete[], don't use dynamic memory allocation to create single objects if you don't have a good reason for it and if you have to, use std::unique_ptr instead of raw new/delete.
int main()
{
myclass my;
my.run();
return 0;
}
This does the same without dynamic allocation.
Related
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);
Ok, if I want to create a heap object with a custom new operator, I know that I need to overload the new operator like this:
void* operator new(size_t size, int unused)
{
void* ptr = malloc(size);
//some custom code
return ptr;
}
And then, if I want to create a heap object using this overloaded operator I would do this:
SomeClass* a = new(0) SomeClass;
The question is: can I do something like this to create a stack object?
I agree with other answers that you probably don't need this but you could do it. See sample code below, just allocate the memory ahead of time and pass it into placement new. You might want to do this if you are using the array new[] form where you might do something like
void *rawMemory = operator new[](25*sizeof(std::stack));
if you had an array of stacks that you had a factory method that managed the resources or something. Either way it depends on your application and use cases. Below shows a simple example
#include <iostream>
#include <stack>
int main ( int argc, char *argv[])
{
void *rawMemory = operator new(sizeof(std::stack<unsigned int>));
std::stack<unsigned int> *s = new (rawMemory) std::stack<unsigned int>;
s->push(10);
std::cout << s->top() << std::endl;
return 0;
}
Second example using the array version, which seems more useful where you may be managing 25 different stacks and handing them to clients. Also, answering your comment. See that the container is defined in the stack definition this time, in this case I am using a vector for the container. Stack is a container but it has an underlying container that defaults to deque
#include <iostream>
#include <stack>
#include <vector>
int main ( int argc, char *argv[])
{
typedef std::stack<unsigned int,std::vector<unsigned int> > StackType;
void *rawMemory = operator new[](25*sizeof(StackType));
StackType *stacks = static_cast<StackType*> (rawMemory);
// allocate
for ( unsigned int i = 0; i < 25; ++i )
{
new (stacks+i) StackType;
}
stacks[1].push(10);
std::cout << stacks[1].top() << std::endl;
// don't forget to delete or smart resize
for ( int i = 24; i >= 0; --i )
{
StackType x;
std::swap ( x, stacks[i] );
}
return 0;
}
You can define a macro like this:
#define STACK_NEW(T) new (alloca(sizeof(T))) T
that uses placement new and alloca() to allocate a block on the stack and construct an object of type T on top of it. You can also define an array version:
#define STACK_NEW_ARRAY(T, n) new (alloca(n * sizeof(T))) T
You'd use this macro in the following ways:
int * p = STACK_NEW(int);
MyObj * q = STACK_NEW(MyObj) (my, constructor, parameters);
int * r = STACK_NEW_ARRAY(int, 42);
You'll have destruct these objects manually:
q->~MyObj();
Deleting them will have undefined behavior.
WARNING: This whole facility is very unsafe. I'd strongly recommend against having such systematically dangerous tools in your codebase. As far as I can see, there is no safe way to use it and it will cause you pain!
I have 3 classes.
class piesa_a{
protected:
int id;
char *tip;
int pret;
public:
[custructor with/without param, display function - works well each one of it]
class piesa_b:public piesa_a
{
private:
float lungime;
bool bw;
public:
[custructor with/without param, display function - works well each one of it]
class piesa_c:public piesa_a
{
private:
int nr;
piesa_b *buf;
public:
piesa_c():piesa_a(){nr=0; buf = new piesa_b[nr];}
piesa_c(int n, piesa_b *bu,int aid, char *tipi, int pretzz):piesa_a(aid,tipi,pretzz)
{
buf = new piesa_b[nr];
for(int i=0;i<nr;i++)
buf[i]= bu[i];
}
void afisare()
{
cout<<nr;
}
In main i have this:
piesa_c C(2, H,14,"TIPC",20);
C.afisare();
But this doesn't work.
I don't know if the "buf" was declared properly because the problem seems to be in last class.
Why?
Later Edit:
The entire code is here: http://pastebin.com/nx2FGSfe.
Now, i have this in main
int main(int argc, char** argv) {
piesa_b *H;
H = new piesa_b[2];
piesa_a A(4,"TIPA",120);
piesa_b B(100,1,3,"TIPA",120);
H[0]=B;
H[1]=B;
piesa_c C(2, H,14,"TIPC",20);
piesa_a** v = new piesa_a*[3];
v[0] = &A;
v[1] = &B;
v[2] = &C;
for(int i=0;i<3;i++)
v[i].afisare();
return 0;
}
The display function return this error
main.cpp:143:14: error: request for member ‘afisare’ in ‘*(v + ((unsigned int)(((unsigned int)i) * 4u)))’, which is of non-class type ‘piesa_a*’
nr is not initialized in the piesa_c() constructor, meaning it will have an undefined value.
Instead of using a dynamically allocated array used a std::vector<piesa_b> instead. It will handle dynamic memory allocation and do the right thing when instances of piesa_c is copied. Using std::vector also means the nr member variable can omitted as that information can be obtained from vector::size() and the std::vector can be populated in the initializer list instead of in the constructor body:
std::vector<piesa_b> buf;
piesa_c(int n,
piesa_b *bu,
int aid,
char* tipi,
int pretzz) : piesa_a(aid,tipi,pretzz),
buf(bu, bu + nr) {}
And to invoke a member function on each element in buf:
// C++11 lambda, otherwise use
// std::vector<piesa_b>::const_iterator.
//
std::for_each(buf.begin(), buf.end(), [](piesa_b& pb) { pb.afisare(); });
If afisare() does not modify then make it const:
void afisare() const
{
}
Additonally, use std::string instead of char*. If you insist on having dynamically allocated members in the classes you need to obey the rule of three.
I am not sure what "not work" means in this context, but when you call this constructor:
piesa_c C(2, H,14,"TIPC",20);
the data member nr is not set. It can have any value that fits into an int, so when you use it to initialize an array you will get variable and weird results.
Note that you could save yourself a lot of trouble by using std::vector and std::string instead of dynamically allocated arrays and char*.
I am trying to create an array of class objects taking an integer argument. I cannot see what is wrong with this simple little code. Could someone help?
#include <fstream>
#include <iostream>
using namespace std;
typedef class Object
{
int var;
public:
Object(const int& varin) : var(varin) {}
} Object;
int main (int argc, char * const argv[])
{
for(int i = 0; i < 10; i++)
{
Object o(i)[100];
}
return 0;
}
In C++ you don't need typedefs for classes and structs. So:
class Object
{
int var;
public:
Object(const int& varin) : var(varin) {}
};
Also, descriptive names are always preferrable, Object is much abused.
int main (int argc, char * const argv[])
{
int var = 1;
Object obj_array[10]; // would work if Object has a trivial ctor
return 0;
}
Otherwise, in your case:
int main (int argc, char * const argv[])
{
int var = 1;
Object init(var);
Object obj_array[10] = { var, ..., var }; // initialize manually
return 0;
}
Though, really you should look for vector
#include <vector>
int main (int argc, char * const argv[])
{
int var = 1;
vector<Object> obj_vector(10, var); // initialize 10 objects with var value
return 0;
}
dirkgently's rundown is fairly accurate representation of arrays of items in C++, but where he is initializing all the items in the array with the same value it looks like you are trying to initialize each with a distinct value.
To answer your question, creating an array of objects that take an int constructor parameter. You can't, objects are created when the array is allocated and in the absence of a trivial constructor your compiler will complain. You can however initialize an array of pointers to your object but you really get a lot more flexibility with a vector so my following examples will use std::vector.
You will need to initialize each of the object separately if you want each Object to have a distinct value, you can do this one of two ways; on the stack, or on the heap. Lets look at on-the-stack first.
Any constructor that take a single argument and is not marked as explicit can be used as an implicit constructor. This means that any place where an object of that type is expected you can instead use an instance of the single parameter type. In this example we create a vector of your Object class and add 100 Objects to it (push_back adds items to a vector), we pass an integer into push_back which implicitly creates an Object passing in the integer.
#include <vector>
int main() {
std::vector<Object> v;
for(int i = 0; i < 100; i++) {
v.push_back(i);
}
}
Or to be explicit about it:
#include <vector>
int main() {
std::vector<Object> v;
for(int i = 0; i < 100; i++) {
v.push_back(Object(i));
}
}
In these examples, all of the Object objects are allocated on the stack in the scope of the for loop, so a copy happens when the object is pushed into the vector. Copying a large number of objects can cause some performance issues especially if your object is expensive to copy.
One way to get around this performance issue is to allocate the objects on the heap and store pointers to the objects in your vector:
#include <vector>
int main() {
std::vector<Object*> v;
for(int i = 0; i < 100; i++) {
v.push_back(new Object(i));
}
for(int i = 0; i < 100; i++) {
delete v[i];
}
}
Since our objects were created on the heap we need to make sure that we delete them to call their deconstructor and, free their memory, this code does that in the second loop.
Manually calling delete has it's own caveats, if you pass these pointers to other code you can quickly loose track of who owns the pointers and who should delete them. An easier way to solve this problem is to use a smart pointer to track the lifetime of the pointer, see either boost::shared_ptr or tr1::shared_ptr which are reference-counted pointers :
#include <vector>
int main() {
std::vector<shared_ptr<Object> > v;
for(int i = 0; i < 100; i++) {
Object* o = new Object(i);
v.push_back(shared_ptr<Object>(o));
}
}
You'll notice that the shared_ptr constructor is explicit, this is done intentionally to make sure that the developer is intentionally stuffing their pointer into the shared pointer. When all references to an object are released the object will automatically be deleted by the shared_ptr, freeing us of the need to worry about it's lifetime.
If you want to stick to arrays, then you must either initialize manually or use the default constructor. However, you can get some control by creating a constructor with a default argument. This will be treated as a default constructor by the compiler. For example, the following code prints out the numbers 0, ..., 9 in order. (However, I'm not sure that the standard dictates that the objects in the array must be constructed in order. It might be implementation dependent, in which case the numbers may appear in arbitrary order.)
#include <iostream>
using namespace std;
struct A {
int _val;
A(int val = initializer()) : _val(val) {}
static int initializer() { static int v = 0; return v++; }
};
int main()
{
A a[10];
for(int i = 0; i < 10; i++)
cout << a[i]._val << endl;
}
Under what circumstances might you want to use multiple indirection (that is, a chain of pointers as in Foo **) in C++?
Most common usage as #aku pointed out is to allow a change to a pointer parameter to be visible after the function returns.
#include <iostream>
using namespace std;
struct Foo {
int a;
};
void CreateFoo(Foo** p) {
*p = new Foo();
(*p)->a = 12;
}
int main(int argc, char* argv[])
{
Foo* p = NULL;
CreateFoo(&p);
cout << p->a << endl;
delete p;
return 0;
}
This will print
12
But there are several other useful usages as in the following example to iterate an array of strings and print them to the standard output.
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
const char* words[] = { "first", "second", NULL };
for (const char** p = words; *p != NULL; ++p) {
cout << *p << endl;
}
return 0;
}
IMO most common usage is to pass reference to pointer variable
void test(int ** var)
{
...
}
int *foo = ...
test(&foo);
You can create multidimensional jagged array using double pointers:
int ** array = new *int[2];
array[0] = new int[2];
array[1] = new int[3];
One common scenario is where you need to pass a null pointer to a function, and have it initialized within that function, and used outside the function. Without multplie indirection, the calling function would never have access to the initialized object.
Consider the following function:
initialize(foo* my_foo)
{
my_foo = new Foo();
}
Any function that calls 'initialize(foo*)' will not have access to the initialized instance of Foo, beacuse the pointer that's passed to this function is a copy. (The pointer is just an integer after all, and integers are passed by value.)
However, if the function was defined like this:
initialize(foo** my_foo)
{
*my_foo = new Foo();
}
...and it was called like this...
Foo* my_foo;
initialize(&my_foo);
...then the caller would have access to the initialized instance, via 'my_foo' - because it's the address of the pointer that was passed to 'initialize'.
Of course, in my simplified example, the 'initialize' function could simply return the newly created instance via the return keyword, but that does not always suit - maybe the function needs to return something else.
If you pass a pointer in as output parameter, you might want to pass it as Foo** and set its value as *ppFoo = pSomeOtherFoo.
And from the algorithms-and-data-structures department, you can use that double indirection to update pointers, which can be faster than for instance swapping actual objects.
A simple example would be using int** foo_mat as a 2d array of integers.
Or you may also use pointers to pointers - lets say that you have a pointer void* foo and you have 2 different objects that have a reference to it with the following members: void** foo_pointer1 and void** foo_pointer2, by having a pointer to a pointer you can actually check whether *foo_pointer1 == NULL which indicates that foo is NULL. You wouldn't be able to check whether foo is NULL if foo_pointer1 was a regular pointer.
I hope that my explanation wasn't too messy :)
Carl: Your example should be:
*p = x;
(You have two stars.) :-)
In C, the idiom is absolutely required. Consider the problem in which you want a function to add a string (pure C, so a char *) to an array of pointers to char *. The function prototype requires three levels of indirection:
int AddStringToList(unsigned int *count_ptr, char ***list_ptr, const char *string_to_add);
We call it as follows:
unsigned int the_count = 0;
char **the_list = NULL;
AddStringToList(&the_count, &the_list, "The string I'm adding");
In C++ we have the option of using references instead, which would yield a different signature. But we still need the two levels of indirection you asked about in your original question:
int AddStringToList(unsigned int &count_ptr, char **&list_ptr, const char *string_to_add);
Usually when you pass a pointer to a function as a return value:
ErrorCode AllocateObject (void **object);
where the function returns a success/failure error code and fills in the object parameter with a pointer to the new object:
*object = new Object;
This is used a lot in COM programming in Win32.
This is more of a C thing to do, in C++ you can often wrap this type of system into a class to make the code more readable.