0

I have the following structure:

typedef struct _DynamicArray {
    int *data = nullptr;
    _DynamicArray *ptr_next = nullptr;
    _DynamicArray *ptr_dim = nullptr;
} DynamicArray; // so that every matrix cell contains another matrix cell

And then the following recursive method:

void _BuildArray(std::string const& source, StringIterator& sit, DynamicArray *dArray, bool& error) {
    if (!error) {
        while (sit+1 < source.length()) {
            ++sit;
            switch (source[sit]) {
                case '[':
                    dArray->ptr_dim = new DynamicArray();
                    _BuildArray(source, sit, dArray->ptr_dim, error);
                    break;
                case ']':
                    return;
                case ',':
                    break;
                case ' ':
                    break;
                default:
                    std::string str;
                    while (std::isdigit(source[sit])) {
                        str.push_back(source[sit]);
                        ++sit;
                    }
                    --sit;
                    if (str.empty()) {
                        error = true;
                        return;
                    }
                    else {
                        dArray->data = new int(stoi(str));
                        dArray->ptr_next = new DynamicArray();
                        dArray = dArray->ptr_next;
                    }
                    break;
            }
        }
    }
}

And then if I pass "[[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []]" as a parameter, it builds the following flatten: "[1,2,6,7,8]" (instead of "[1,2,3,4,5,6,7,8]"). Why?

The calling snippet is this:

StringIterator sit = 0;
bool error = false;
this->dynArray = new DynamicArray();
_BuildArray(this->listString, sit, this->dynArray, error);
2
  • I don't get it, you use std::string and then you want to complicate life yourself with raw pointers while you have so many facilities in C++ like std::list, std::vector.. Commented Jul 20, 2015 at 20:44
  • @Jack Anyway, how would you do that using std::list and std:vector (what would be the structure) ? Commented Jul 20, 2015 at 21:17

2 Answers 2

1

Once your recursive _BuildArray call returns, you don't advance dArray like you do in the default: case. Meaning the next [ you encounter will overwrite the results of the previous [.

Sign up to request clarification or add additional context in comments.

2 Comments

If I embed a trace if (dArray->data!=nullptr) {std::cout << "OVERWRITE\n";} before the dArray->data = new int(stoi(str));, it prints nothing.
@AndrejsIgumenovs No you've misunderstood. Say you get [], []in the input string. It will allocate dArray->ptr_dim and recurse into the function, then return at the ]. The next [] does the same thing, overwriting the previous ptr_dim.
0

This answer is just to clarify my comment, I was talking about a structure which utilizes C++ STL structures to avoid having to manually manage allocations and dynamic memory, something like:

class CellVisitor
{
public:  
  virtual accept(Cell* cell) = 0;
};

class Cell
{
public:
  virtual void visit() = 0;

};

class ContainerCell : public Cell
{
private:
  std::vector<std::unique_ptr<Cell>> cells;

public:
  void addCell(...) { ... }

  void visit(CellVisitor* visitor) override
  {
    visitor->accept(this);
    for (auto& cell : cells)
      cell->visit();
  }
};

class IntegerCell : public Cell
{
private:
  std::vector<int> data;

public:
  void visit(CellVisitor* visitor) override
  {
    visitor->accept(this);
  }
}

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.