EMBLEM
EMBLEM

Reputation: 2265

C++: Passing a (pointer to an?) array of objects by reference

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.

Upvotes: 1

Views: 117

Answers (4)

FrogTheFrog
FrogTheFrog

Reputation: 1671

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;
}

Upvotes: 1

txtechhelp
txtechhelp

Reputation: 6777

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.

Upvotes: 0

bames53
bames53

Reputation: 88175

    *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.

Upvotes: 0

Joseph
Joseph

Reputation: 599

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

Upvotes: 1

Related Questions