Author Topic: [SOLVED] Problem: Arduino, template class for dynamic 2D array  (Read 687 times)

0 Members and 1 Guest are viewing this topic.

Offline NightMothTopic starter

  • Contributor
  • Posts: 38
  • Country: cn
Hello all

I'm trying to implement a template class for dynamic 2D arrays for my arduino project.
I'm using Aruino IDE 1.8.19 with default settings.
Target board - Arduino Nano V3.

Problemm summary: Code compiles, but works correctly only for byte and int types, and doesnt work for double and unsigned long types (even though I'm using "template <typename T>" statements).

I'm guess there is some problemm with double pointer indexing/pointer arythmetics,
but I have no idea how to solve it. I will very appreciate if somebody can check it.

Detailed problemm description (expected vs actual output) is in comments in my code below.

".ino" file - detailed problemm description is here
Code: [Select]
#include "Dynamic2DArr.h"


void setup() {
  // put your setup code here, to run once:

  Serial.begin(9600);

  // Create 4-rows 3-cols 2D array for doubles
  // (Default values will be "7")
  Dynamic2DArr<double> dynX(4, 3);
        // Debugger serial output from constructor - as expected:
        // Why it is as expected here, but not es expected later??
        // "Arr[0][0]=7.00;Arr[0][1]=7.00;Arr[0][2]=7.00;
        //  Arr[1][0]=7.00;Arr[1][1]=7.00;Arr[1][2]=7.00;
        //  Arr[2][0]=7.00;Arr[2][1]=7.00;Arr[2][2]=7.00;
        //  Arr[3][0]=7.00;Arr[3][1]=7.00;Arr[3][2]=7.00;"

  // display array using indexing
  dynX.dispArr();
        // PROBLEM:
        // Expected serial output:
        // "Dynamic2DAr::dispArr() start
        //  7.00; 7.00; 7.00;
        //  7.00; 7.00; 7.00;
        //  7.00; 7.00; 7.00;
        //  7.00; 7.00; 7.00;
        //  Dynamic2DAr::dispArr() end"
        // Actual serial output:
        // "Dynamic2DAr::dispArr() start
        //  7.00; 0.00; 0.00;
        //  7.00; 0.00; 0.00;
        //  7.00; 0.00; 0.00;
        //  7.00; 7.00; 7.00;
        //  Dynamic2DAr::dispArr() end"


  // display array using getters and setters
  check2DArr(dynX);
        // PROBLEM:
        // Expected serial output:
        // "FUNCTION check2D()
        //  7.00; 7.00; 7.00;
        //  7.00; 7.00; 7.00;
        //  7.00; 7.00; 7.00;
        //  7.00; 7.00; 7.00;
        // Actual serial output:
        // "FUNCTION check2D()
        //  7.00; 0.00; 0.00;
        //  7.00; 0.00; 0.00;
        //  7.00; 0.00; 0.00;
        //  7.00; 7.00; 7.00;


  // Fill array with data
  dynX.setVal(0, 0, 11);  dynX.setVal(0, 1, 12);  dynX.setVal(0, 2, 13);
  dynX.setVal(1, 0, 21);  dynX.setVal(1, 1, 22);  dynX.setVal(1, 2, 23);
  dynX.setVal(2, 0, 31);  dynX.setVal(2, 1, 32);  dynX.setVal(2, 2, 33);
  dynX.setVal(3, 0, 41);  dynX.setVal(3, 1, 42);  dynX.setVal(3, 2, 43);

  // display array using indexing
  dynX.dispArr();
        // PROBLEM:
        // Expected serial output:
        // "Dynamic2DAr::dispArr() start
        //  11.00; 12.00; 13.00;
        //  21.00; 22.00; 23.00;
        //  31.00; 32.00; 33.00;
        //  41.00; 42.00; 43.00;
        //  Dynamic2DAr::dispArr() end"
        // Actual serial output:
        // "Dynamic2DAr::dispArr() start
        //  11.00; 0.00; 0.00;
        //  21.00; 0.00; 0.00;
        //  31.00; 0.00; 0.00;
        //  41.00; 42.00; 43.00;
        //  Dynamic2DAr::dispArr() end"

  // display array using getters and setters
  check2DArr(dynX);
        // PROBLEM:
        // Expected serial output:
        // "Dynamic2DAr::dispArr() start
        //  11.00; 12.00; 13.00;
        //  21.00; 22.00; 23.00;
        //  31.00; 32.00; 33.00;
        //  41.00; 42.00; 43.00;
        //  Dynamic2DAr::dispArr() end"
        // Actual serial output:
        // "Dynamic2DAr::dispArr() start
        //  11.00; 0.00; 0.00;
        //  21.00; 0.00; 0.00;
        //  31.00; 0.00; 0.00;
        //  41.00; 42.00; 43.00;
        //  Dynamic2DAr::dispArr() end"


}

void loop() {
  // put your main code here, to run repeatedly:

}

template <typename T>
void check2DArr(Dynamic2DArr<T> &dynArr)
{
  Serial.println(F("FUNCTION check2D()"));
 
  int rows = dynArr.getRowsCnt();
  int cols = dynArr.getColsCnt();

  for(int i = 0; i < rows; i++)
  {
    for(int j = 0; j < cols; j++)
    {
      Serial.print(dynArr.getVal(i,j));
      Serial.print(F("; "));
    }
    Serial.println();
  }
}

".h" file
Code: [Select]
#ifndef DYNAMIC2DARR_H
#define DYNAMIC2DARR_H

#include <Arduino.h>

#define DEBUG_MODE

template <typename T>
class Dynamic2DArr
{
  private:
    int rows_cnt;
    int cols_cnt;

    T** Arr;

  public:
 
    Dynamic2DArr(int rows_cnt, int cols_cnt);
    ~Dynamic2DArr();

    int getRowsCnt();
    int getColsCnt();   
    void setVal(int row_idx, int col_idx, T val);
    T getVal(int row_idx, int col_idx);
    T** getArrPtr();   
     
    void dispArr();
};


template <typename T>
Dynamic2DArr<T>::Dynamic2DArr(int rows_cnt, int cols_cnt)
{
  #ifdef DEBUG_MODE
    Serial.println(F("Constructor Dynamic2DAr::Dynamic2DArr() start"));
  #endif
 
  this->rows_cnt = rows_cnt;
  this->cols_cnt = cols_cnt;

  this->Arr = new T*[rows_cnt]; 
  for(int row = 0; row <  this->rows_cnt; row++)
  {
    this->Arr[row] = new T(this->cols_cnt);
   
    #ifdef DEBUG_MODE
      Serial.print(F("row # "));
      Serial.print(row);
      Serial.print(F(" columns added "));
      Serial.println(this->cols_cnt);
    #endif
  }

  for(int row = 0; row <  this->rows_cnt; row++)
  {
    for(int col = 0; col <  this->cols_cnt; col++)
    {
      this->Arr[row][col] = 7;

      #ifdef DEBUG_MODE
        Serial.print(F("Arr["));
        Serial.print(row);
        Serial.print(F("]["));
        Serial.print(col);
        Serial.print(F("]="));
        Serial.print(this->Arr[row][col]);
        Serial.print(F(";"));
      #endif     
    }
    #ifdef DEBUG_MODE
      Serial.println();
    #endif
  }

  #ifdef DEBUG_MODE
    Serial.println(F("Constructor Dynamic2DAr::Dynamic2DArr() end"));
  #endif
}


template <typename T>
Dynamic2DArr<T>::~Dynamic2DArr()
{
  #ifdef DEBUG_MODE
    Serial.println(F("Destructor Dynamic2DAr::~Dynamic2DArr() start"));
  #endif
 
  for(int row = 0; row < rows_cnt; row++)
  {
    delete[] this->Arr[row];
  }
  delete[] this->Arr;   
  this->Arr = NULL;
 
  #ifdef DEBUG_MODE
    Serial.println(F("Destructor Dynamic2DAr::~Dynamic2DArr() end"));
  #endif
}


template <typename T>
int Dynamic2DArr<T>::getRowsCnt()
{
  return rows_cnt;
}


template <typename T>
int Dynamic2DArr<T>::getColsCnt()
{
  return cols_cnt;
}


template <typename T>
void Dynamic2DArr<T>::setVal(int row_idx, int col_idx, T val)
{

  this->Arr[row_idx][col_idx] = val;
 
  #ifdef DEBUG_MODE
    Serial.print(F("Dynamic2DAr::setVal() Arr["));
    Serial.print(row_idx);
    Serial.print(F("]["));
    Serial.print(col_idx);
    Serial.print(F("]="));
    Serial.print(Arr[row_idx][col_idx]);
    Serial.println(F(" Done;"));
  #endif     
}


template <typename T>
T Dynamic2DArr<T>::getVal(int row_idx, int col_idx)
{
  return this->Arr[row_idx][col_idx];
}


template <typename T>
T** Dynamic2DArr<T>::getArrPtr()
{
  return this->Arr;
}


template <typename T>
void Dynamic2DArr<T>::dispArr()
{

  #ifdef DEBUG_MODE
    Serial.println(F("Dynamic2DAr::dispArr() start"));

    for(int row = 0; row < this->rows_cnt; row++)
    {
      for(int col = 0; col < this->cols_cnt; col++)
      {
        Serial.print(this->Arr[row][col]);
        Serial.print(F("; "));
      }
      Serial.println();
    }

    Serial.println(F("Dynamic2DAr::dispArr() end"));
  #endif
}

#endif

".cpp" file
Code: [Select]
#include "Dynamic2DArr.h"

// By some reason can compiller throws error when
// template functions declarations and definitions are
// separated in .h and .cpp file
// all template functions definitiona are in .h file




« Last Edit: April 27, 2026, 12:53:40 pm by NightMoth »
 

Offline xvr

  • Frequent Contributor
  • **
  • Posts: 909
  • Country: ie
    • LinkedIn
Re: Problem: Arduino, template class for dynamic 2D array
« Reply #1 on: April 27, 2026, 11:39:24 am »
This line
Code: [Select]
    this->Arr[row] = new T(this->cols_cnt);should be
Code: [Select]
    this->Arr[row] = new T[this->cols_cnt];(Wrong type of breackets)
 
The following users thanked this post: NightMoth

Offline NightMothTopic starter

  • Contributor
  • Posts: 38
  • Country: cn
Re: Problem: Arduino, template class for dynamic 2D array
« Reply #2 on: April 27, 2026, 12:53:05 pm »
This line
Code: [Select]
    this->Arr[row] = new T(this->cols_cnt);should be
Code: [Select]
    this->Arr[row] = new T[this->cols_cnt];(Wrong type of breackets)

THANK YOU! This is it! Problem solwed!
Because of this stupid typo, I was stuck for two evenings...
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf