Mechatrnk
Mechatrnk

Reputation: 111

Setting-up a 2D array using std::Vector

I have already improved my array from this question in order to be created within a class, I also kind of optimized it using std::vector so it is not allocated on a heap but on a stack and thus it is faster and also I do not have to manage the memory manually.

But I was not able to create a function which would set a value to an element. I got errors like expression must have pointer-to-object type (when I try to declare my element as int cell or an array may not have element of this type (when I try to declare it as int cell[][]) and I get a segmentation error when I try to declare it like this int *cell[].

Here is my code

.hpp

#pragma once
#include <iostream>
#include <vector>
class myPlan 
{ 
    int slots; 
    int rows = 3;
    int cell[][];
  
public: 

    myPlan(int slots);  
    
    void setCellValue(int row, int slot, int value)
 };

.cpp

#include "myPlan.hpp"

myPlan::myPlan(int slots) 
{ 
   this->slots = slots;

   std::vector<std::vector<int> > cell(STATUS_N);
   for (int i = 0; i < STATUS_N; i++) 
   { 
        // declare  the i-th row to size of column 
        cell[i] = std::vector<int>(slots); 
   }

  //Print the array
    for (int i = 0; i < STATUS_N; i++) { 
        for (int j = 0; j < cell[i].size(); j++) 
         {
            cell[i][j] = 0;
            std::cout << cell[i][j] << " "; 
         }
        std::cout << "\n"; 
    } 
} 


void myPlan::setCellValue(int row, int slot, int value)
{
    cell[row][slot] = value;
}

main.cpp

#include "myPlan.hpp"

int main() 
{ 
    myPlan plan(N_PLAN); 
    
    plan.setCellValue(0,2,42);
}

Thank you very much in advance for any help P.S. I hope that this is more optimal than this array, if there was even better optimized version, I would be glad to learn about it.

Upvotes: 0

Views: 119

Answers (2)

Vasilij
Vasilij

Reputation: 1941

As far as I understood your problem, you need an array of arrays (a number of slots), which size is known at compile time. And you prefer it to be on the stack.

I encourage you to use std::array and forget about C-style arrays ([] - these guys). Or better learn the difference between them and make your own mind.

There is an example how to use it. The class has to be templated to provide parameters of the array sizes at compile time. It is pretty straighforward, but if you don't need it, you can just remove the template line before the class definition and replace RowNumber and SlotSize with you defines or constants known at compile time.

This solution will only work if sizes are known at compile time. If you want to provide the number of rows as myPlan constructor parameter, then you'll need to dynamically allocate memory and use std::vector or something similar.

#include <iostream>
#include <array>

template<std::size_t RowNumber, std::size_t SlotSize>
class myPlan { 
    std::array<std::array<int, SlotSize>, RowNumber> cells;
  
public: 
    myPlan() : 
    cells{} // initialize array with zeros
    {  
        //Print the array
        for (int i = 0; i < cells.size(); i++) { 
            for (int j = 0; j < cells[i].size(); j++) 
            {
                std::cout << cells[i][j] << " "; 
            }
            std::cout << "\n"; 
        }       
    }
    
    void setCellValue(int row, int slot, int value) {
        cells[row][slot] = value;
    }
};

#define N_PLAN 4
#define STATUS_N 3

int main() 
{ 
    myPlan<N_PLAN, STATUS_N> plan;    
    plan.setCellValue(0,2,42);
}

Upvotes: 1

john
john

Reputation: 87932

So here's what I think is the fundamental problem, it has nothing to do with arrays or vectors. You are just handling your class variable incorrectly. Here's your class

class myPlan 
{ 
    int slots; 
    int rows = 3;
    int cell[][];

int cell[][]; is not legal C++, but we'll let that pass. The point is that you have some kind of 2D array called cell in your class.

Now here's your constructor

myPlan::myPlan(int slots) 
{ 
   this->slots = slots;

   std::vector<std::vector<int> > cell(STATUS_N);
   for (int i = 0; i < STATUS_N; i++) 
   { 
        // declare  the i-th row to size of column 
        cell[i] = std::vector<int>(slots); 
   }

Now here you've declared a 2D vector called cell. But (and here's the point) this is not the same cell that's in your class, it a completely separate variable which just happens to have the same name. And like any variable declared inside a function it will no longer exist after the function exits.

Here's how it should be done.

class myPlan 
{ 
    int slots; 
    int rows = 3;
    std::vector<std::vector<int> > cell;
    ...

myPlan::myPlan(int slots) 
{ 
   this->slots = slots;

   cell.resize(STATUS_N);
   for (int i = 0; i < STATUS_N; i++) 
   { 
        // declare  the i-th row to size of column 
        cell[i] = std::vector<int>(slots); 
   }

See the difference? I didn't declare a new cell variable, I just resized the one that is declared in the class.

Upvotes: 3

Related Questions