0

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.

Mechatrnk
  • 101
  • 1
  • 13
  • " so it is not allocated on a heap but on a stack and thus it is faster." sorry, but `std::vector` does store its elements on the heap. Perhaps you were looking for `std::array` – 463035818_is_not_an_ai Oct 02 '20 at 13:05
  • Vectors allocate the memory for their elements from the heap. The vector **itself** might be on the stack. It's exactly the same siutation as with a pointer, the pointer itself might be on the stack, but the memory it points to is on the heap. – john Oct 02 '20 at 13:05
  • please include the error message verbatim, please do not summarize or paraphrase it – 463035818_is_not_an_ai Oct 02 '20 at 13:06
  • See this example: https://gist.github.com/Const-me/7aee0ef4087d250cc9b82463988ecafc – Soonts Oct 02 '20 at 13:08
  • `int cell[][];` -- What is this supposed to do? This is not valid C++. – PaulMcKenzie Oct 02 '20 at 13:08
  • ot: another nitpick on wording: "optimal" means nothing when you don't say what you optimize for. You can optimize for speed, memory usage, simplicity of the code, etc.. but usually not all at once – 463035818_is_not_an_ai Oct 02 '20 at 13:10
  • for 2d arrays you have to decide first: Does it need to be resizable at runtime? Are rows with different number of elements allowed? Depending on the answers there are several options (and none is optimal always) – 463035818_is_not_an_ai Oct 02 '20 at 13:12
  • Thank you for your updates, I learned the stack/heap allocation wrongly, my fault. @idclev463035818 What concerns other points, for me optimal would mean as fast code as possible with as small memory demands as possible. What concerns the decisions made, the size of the array would be constant (the elements would be sorted later, but there is no need for expanding nor shrinking) and all rows have to have same amount of elements (for example 3x10) – Mechatrnk Oct 02 '20 at 13:18
  • @Mechatrnk don't optimize if you don't have to. Optimize the part that need optimization. However, don't pessimize either. For example, for a matrix like data structure, you would be better off with a one dimentional vector, mapped as a square. – Guillaume Racicot Oct 02 '20 at 13:21
  • @john um, i had to look it up and still got it wrong :/ – 463035818_is_not_an_ai Oct 02 '20 at 13:35
  • then you are looking for a `std::array< std::array,3>` – 463035818_is_not_an_ai Oct 02 '20 at 13:35
  • Thank you to all.I jumped to C++ less than a month ago from Python and so there is a ton of concepts which Python user does not need to take care of, so it is sometimes confusing to me, but thank you once again, this is a great school for me :) – Mechatrnk Oct 02 '20 at 13:54

2 Answers2

3

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.

john
  • 85,011
  • 4
  • 57
  • 81
1

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);
}
Vasilij
  • 1,861
  • 1
  • 5
  • 9