1

I'm new to C++, and I'm having significant trouble with creating an array of objects using a pass by pointer and reference. This is not the actual code; it's an example of what the code essentially does.

#include <iostream>

class MyClass
{
    public:
        MyClass();
        static int doStuff(MyClass *&classArray);
        void print_number();

    private:
        int number;
};

MyClass::MyClass()
{

}

int MyClass::doStuff(MyClass *&classArray)
{
    int i = 0;
    for (i = 0; i < 10; i++) {
        *classArray[i].number = i;
    }
    return i;
}

void MyClass::print_number()
{
    std::cout << number << "\n";
}

int main(void)
{
    MyClass *test = nullptr;
    int p = MyClass::doStuff(test);
    std::cout << p << '\n';
    for (int i = 0; i < 10; i++) {
        test[i].print_number();
    }
    return 0;
}

When compiled, this gives a segmentation fault.

3
  • You never allocate memory to hold instances of MyClass. You should write (in main) MyClass test[10]; instead of MyClass *test = NULL; Commented Feb 14, 2014 at 21:42
  • @leemes My mistake: in the actual code it's MyClass *class = nullptr. I'll fix that. Commented Feb 14, 2014 at 21:45
  • That's more or less the same. Both don't allocate any memory. I said MyClass test[10]; Commented Feb 14, 2014 at 21:47

4 Answers 4

1

This is how you do it (don't forget do delete classArray with delete[] at the end of your program or destructor:


new operator has to have default constructor, if you want to use non-default it is easier to create copy constructor, then a temporary object and copy.

#include <iostream>

class MyClass
{
public:
    MyClass();
    MyClass(int x, int y);
    MyClass(MyClass &OldClass);
    static int doStuff(MyClass *&classArray, int Size, int x, int y);
    void print_number();

private:
    int number, x, y;
};

MyClass::MyClass()
{
    number = 0;
    x = 0;
    y = 0;
}

MyClass::MyClass(int x, int y)
{
    number = 0;
    this->x = x;
    this->y = y;
}

MyClass::MyClass(MyClass &OldClass)
{
    this->number = OldClass.number;
    this->x = OldClass.x;
    this->y = OldClass.y;
}

int MyClass::doStuff(MyClass *&classArray, int Size, int x, int y)
{
    if (Size > 0)
    {
        classArray = new MyClass[Size];
        for (int i = 0; i < Size; i++)
        {
            classArray[i] = MyClass(x, y);
            classArray[i].number = i;
        }

        return Size;
    }
    else
        return 0;
}

void MyClass::print_number()
{
    std::cout << number << " " << x << " " << y << "\n";
}

int main(void)
{
    MyClass *test = nullptr;
    int p = MyClass::doStuff(test, 10, 5, 6);
    std::cout << p << '\n';
    for (int i = 0; i < p; i++) {
        test[i].print_number();
    }
    delete[] test;
    std::cin.get();
    return 0;
}
Sign up to request clarification or add additional context in comments.

2 Comments

The actual class has a constructor that I've set up to take two arguments. How would I factor this in—something like MyClass insertedClass(arg1, arg2); classArray[i] = inserted class?
I'll try to give you an example in a sec.
1

It is not working because you need to allocate the array, as the function is trying to access elements of an array which has yet not been initialized to hold that amount of elements. You can do this by

MyClass *test = new MyClass[array_size];

Or

MyClass test[array_size];

Or by using a resizable container such as std::vector, and changing the function parameters accordingly

Comments

0
    *classArray[i].number = i;

You called doStuff with a null pointer, so classArray is null and is not an array. Dereferencing a null pointer results in undefined behavior and on most implementations you'll usually get a crash.


You're also dereferencing something that's not a pointer so this code will not even compile. The error I get is:

main.cpp:23:9: error: indirection requires pointer operand ('int' invalid)
        *classArray[i].number = i;
        ^~~~~~~~~~~~~~~~~~~~~

Presumably this is just because, as you say, the code you're showing is not your real code and classArray[i].number corresponds to a pointer in your real code. But I thought I'd point this out anyway, just in case.

Comments

0

Given the context of your code, here's a working example of your code:

#include <iostream>

class MyClass
{
    public:
        MyClass() {}

        static int doStuff(MyClass*& classArray, size_t sz)
        {
            int i = 0;
            for (; i < sz; i++) {
                classArray[i].number = i;
            }
            // not sure what you want here, but this will return sz+1 if sz>0
            return i;
        }

        void print_number()
        {
            std::cout << this->number << std::endl;
        }

    private:
        int number;
};

int main(void)
{
    MyClass* test = new MyClass[10];
    int p = MyClass::doStuff(test, 10);
    std::cout << p << '\n';
    for (int i = 0; i < 10; i++) {
        test[i].print_number();
    }
    delete[] test;
    return 0;
}

Though as others have pointed out, you are using C++, while it's a great exercise in understand how to pass pointers and arrays around, you might find the STL and C++stdlib contain a lot of these types of idioms in an 'easier to understand context'.

Here's your code with some C++ STL:

#include <iostream>
#include <vector>

class MyClass
{
    public:
        MyClass() {}
        MyClass(int i) : number(i) {}

        static int doStuff(std::vector<MyClass>& classArray, size_t sz)
        {
            int i = 0;
            for (; i < sz; i++) {
                classArray.push_back(MyClass(i));
            }
            // not sure what you want here, but this will return sz+1 if sz>0
            return i;
        }

        void print_number()
        {
            std::cout << this->number << std::endl;
        }

    private:
        int number;
};

int main(void)
{
    std::vector<MyClass> test;
    int p = MyClass::doStuff(test, 10);
    std::cout << test.size() << '\n';
    // can use iterators here if you want
    std::vector<MyClass>::iterator itr = test.begin();
    for (; itr != test.end(); itr++) {
        itr->print_number();
    }
    return 0;
}

Hope that can help.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.