-1

Recently, I started to learn C++ after I have learned Java, and I was instructed to make a dynamic array, so I tried to make a temp variable which contains what I need and then reassign it into the variable I actually want to use.

void Pile::grow(Stone s){
    Stone temp[getLength() + 1];
    for (int i = 0; i < sizeof(temp) / sizeof(temp[0]); ++i) {
        if (sizeof(temp) / sizeof(temp[0]) < 28){
            temp[i] = stoneArr[i];
        }
    }
        
    stoneArr = temp;
}

But the compiler is giving me an error that I cannot reassign it, for some reason I just can't understand.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Use `std::vector` instead of C array. and it'll be fine. Don't use C arrays like this. It is not a dynamic array! For that you must know the array size at compile time what you don't know there... Also what is `stoneArr`? It is not java. Forget everything about that. You are much closer to the metal now... – simre May 15 '22 at 11:22
  • This is explained in any beginner level [good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). In particular, the size of an array must be a compile time constant. `std::vector` can/should be used here. – Jason May 15 '22 at 11:24
  • What's the significance of the number `28` here? – Nathan Pierson May 15 '22 at 11:25
  • i will try and use vectors guys, thank you :) – Shai Susana May 15 '22 at 11:29

1 Answers1

0

void Pile::grow(Stone s)

You are not using s anywhere. Are you supposed to add it to the new array you are trying to create?

Stone temp[getLength() + 1];

This is not legal in standard C++. The size of a fixed array must be known at compile time.

Some compilers support "variable length arrays" as a non-standard extension, but do not rely on them if you need to write portable code. See Why aren't variable-length arrays part of the C++ standard?

To allocate an array dynamically at runtime, use the new[] operator instead, eg:

Stone *temp = new Stone[getLength() + 1];
...
delete[] temp;

Or, use the standard std::vector container instead, eg:

#include <vector>

std::vector<Stone> temp(getLength() + 1);
...

for (int i = 0; i < sizeof(temp) / sizeof(temp[0]); ++i)

You cannot use this sizeof trick on a dynamic array, let alone a VLA. sizeof is evaluated only at compile time, not at runtime.

Since you are copying values from an existing array, use the length of that array instead:

for (int i = 0; i < getLength(); ++i)

if (sizeof(temp) / sizeof(temp[0]) < 28)

Hard-coding a 28 here makes no sense. In fact, this whole if check needs to be removed completely.

stoneArr = temp;

This assignment will not work when temp is a VLA. And stoneArr can't be a VLA anyway.

stoneArr needs to be either a Stone* pointer to a new[]'d array (that is managed by following the Rule of 3/5/0), or a std::vector<Stone> (preferred).

With all of that said, try this instead:

private:
    Stone *stoneArr;
    int arrLength;

...


Pile::Pile()
    : stoneArr(NULL), arrLength(0) {
}

Pile::Pile(const Pile &src)
    : stoneArr(new Stone[src.arrLength]), arrLength(src.arrLength) {
    for (int i = 0; i < arrLength; ++i) {
        stoneArr[i] = src.stoneArr[i];
    }
}

Pile::~Pile() {
    delete[] StoneArr;
}

Pile& Pile::operator=(const Pile &rhs) {
    if (&rhs != this) {
        Pile temp(rhs);
        std::swap(stoneArr, temp.stoneArr);
        std::swap(arrLength, temp.arrLength);
    }
    return *this;
}

int Pile::getLength() const {
    return arrLength;
}

void Pile::grow(const Stone &s){
    Stone *temp = new Stone[arrLength  + 1];
    for (int i = 0; i < arrLength; ++i) {
        temp[i] = stoneArr[i];
    }
    temp[arrLength] = s;
        
    delete[] stoneArr;
    stoneArr = temp;
    ++arrLength;
}

Or:

#include <vector>

private:
    std::vector<Stone> stoneArr;

...

// std::vector follows the rule of 3/5/0, so let the
// compiler handle Pile(), Pile(const Pile &), ~Pile(),
// and operator= for you...

int Pile::getLength() const {
    return stoneArr.size();
}

void Pile::grow(const Stone &s){
    stoneArr.push_back(s);
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770