Array related class problem

Hello everybody,

I want to make a small class witch containes an array of ints and an int to hold the length of the array.
The class works fine but when i use my latest function: “show” things start to get weird.
This is my class:

class intArray{

  private :
    int list[];
    int len;
  public :
    intArray(int);
    intArray(int,int array[]);
    void show();
    int get(int);
    int length();
};

intArray::intArray(int l){
  list[l];
  len = l;
}
intArray::intArray(int l,int rij[]){
  list[l];
  len = l;
  for(int i=0;i < l;i++){list[i] = rij[i];}
}
void intArray::show(){
  for(int i = 0;i < len;i++){
    Serial.print(list[i]);Serial.print(" ");
  }
  Serial.println("");
}
int intArray::get(int index){if(index < len){return list[index];}}
int intArray::length(){return len;}

When I run this file everything goes fine:

void setup(){Serial.begin(9600);}
void loop(){

  int var[6] = {13,-8,7,-4,9,4};
  intArray array(6,var);
  Serial.println(array.length());
  delay(5000);
}

But when i run this one I get some weird numbers over the Serial Port:

void setup(){Serial.begin(9600);}
void loop(){

  int var[6] = {13,-8,7,-4,9,4};
  intArray array(6,var);
  Serial.println(array.length());
  array.show();
  delay(5000);
}

Any ideas of what went wrong?
It would be really helpfull.

Thank You,
Knockstaart

  private :
    int list[];

It's hard to believe that this even compiles. You are not specifying a size for this array.

intArray::intArray(int l){
  list[l];
  len = l;
}

What do you think that the list[l] statement is doing? It is not setting the size of the array.

The goal of this class was to make an object that holts an array (any size given by the user) and the size of this array.
It has a function to return an int on index x, change it,…
Now I want a function that prints the array over the serial port.

When i use this code everything is fine:

void setup(){Serial.begin(9600);}
void loop(){

  int var[6] = {13,-8,7,-4,9,4};
  intArray array(6,var);
  Serial.println(array.length());
  for(int i = 0;i < array.length();i++){
    Serial.print(array.get(i));
    Serial.print(" ");
  }
  Serial.println("");
  delay(5000);
}

I get 2 nice lines over the serial port:

6
13 -8 7 -4 9 4

When i use the show() function, whitch does the same, only in a function, it gives me:

13
13 -8 7 -4 9 4 4 + some random numbers

It seems that the show function somehow changed the private variable ‘len’. (It uses the int list[0], it seems)
How is this posible?
I agree this is not the best way to do it. Is there a way to include an array to my class without a fixed size, whitch is declared by the constructor?

Thank you for your help,
Knockstaart

This statement references some element in the array:

  list[l];

It does nothing with the value in that array. It is NOT setting the size of the array.

You still have an array that can hold 0 elements.

  for(int i=0;i < l;i++){list[i] = rij[i];}

It is generally not a good idea to write more values to an array than the array can hold.

You either need to define some static sized array that defines an upper limit on the size of the array, or make list a pointer, and dynamically allocate space for the data (not necessarily advised, given how little memory the Arduino has).

You can not set the size of an array at run time the way you are trying to do it. Period.

Thank you for your reply. I'll read some more on the internet about arrays and pointers in C++.

knockstaart

jesus paul hes using i and an indicator for a user defined set. it doesnt need to be specified. its common logic when dealing with things such. i deal with these things ALL the time. im a software engineering/computer enginnering student at UH. and btw to op. i think in ur first code looks like u have "intarray" with no spaces. idk if that was a mistake but looks likeit probly would be. i actually understand what ur doing here. didnt go over the whole thing but ur logic seemed fine.

paul classes dont need values. they refrence points. its completely fine for i to be used. good logic to op. im impressed. but i “think” ur show functions not working because there never was a show function.

you have intarray::show().

which calls something in intarray but problem is though its there. there is nothing in it. what you could do is creat show() and then call it from within intarray(). for now ur using an empty function. i’ll give you an example of a recent libarry i created for a friend.

its a rather simple controller for a project he was working on. works fine and everything and makes coding his project pretty simple too. there may be a flaw or two cause i just edited it slightly but as far as i can see on his table its perfect

anyway i use similar structure with “blank arrays” (lol) there all user defined and such. though i dont use classes just functions iether way works pretty well. may update it soon but its gettin the job done for something that took me like 10 or 20 minutes to write.

#ifndef Table_Runner
#define Table_Runner
#include <avr/interrupt.h>
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"


#else
#include "WProgram.h"
#endif

int redcon(int a,int c,int d,int e,int f[20],int F[20]) {
	int asf;
	
	
		a= analogRead(c); 
	
		a = map(a, d,e, 0, 4095);
	
		a = constrain(a, 0, 4095); 
  for(asf=0;asf<20;asf++) {
	  Tlc.set(f[asf],a);
      //Tlc.set(F[asf],a);
  }
  Tlc.update();
  }

  int clr_pkr(int a,int A,int E,int I,int t, int T,int c,int C,int D,int Q,int w,int W,int d,int e,int f,int F,int G) {
	int x=0;
	int X=0;
	int x1=0;
	int ar[]={0,10,20};
	int ae[]={0,10,20};
	int aw[]={10,20,0};



 
	Tlc.set(2,4095);
	Tlc.set(19,4095);
	Tlc.set(29,4095);

	Tlc.set(1,4095);
	Tlc.set(11,4095);
	Tlc.set(21,4095);
	Tlc.set(8,4095);
	Tlc.set(18,4095);
	Tlc.set(28,4095);
 // read the sensor:
		a= analogRead(c); 
	    A= analogRead(C);
		E= analogRead(D);
		I= analogRead(Q);
		t= analogRead(w);
		T= analogRead(W);
  // apply the calibration to the sensor reading
	
		a = map(a, d,e, 0, 4095);
		A = map(A, d,e, 0, 4095);
		E = map(E, d,e, 0, 4095);
		I = map(Q, d,e, 0, 4095);
		t = map(w, d,e, 0, 4095);
		T = map(W, d,e, 0, 4095);
   // in case the sensor value is outside the range seen during calibration
	
		a = constrain(a, 0, 4095); 
		A = constrain(A, 0, 4095);
		E = constrain(E, 0, 4095);
		I = constrain(Q, 0, 4095);
		t = constrain(t, 0, 4095);
		T = constrain(T, 0, 4095);
  
	  while(I>200) {
		  if(a>0&&a<200) {
		     	 Tlc.set(f,x+5);
			if(x>4080)
				 Tlc.set(f,x-5);
		  }
		  if(A>0&&A<200) {
		     	 Tlc.set(f,X+5);
			if(X>4080)
				 Tlc.set(f,X-5);
		  }
		  if(E>0 && E<200) {
		     	 Tlc.set(f,x1+5);
			if(x1>4080)
				 Tlc.set(f,x1-5);
		  }
			for(int m=0;m<3;m++) {
		  if(t>0 && t<200 && I>200) {
			  Tlc.set(ar[m],4095);
			  Tlc.update(); } 
		  else 
		  if(I<200) m=3;
		  }
		  
				for(int m=0;m<3;m++) {
		  if(T>0 && T<200 && I>200) {
			  Tlc.set(ae[m],4095);
			  Tlc.set(aw[m],4095);
			  Tlc.update(); }
		  else 
		  if(I<200) m=3;
		  }
		  
	  
	  }
  }

  int grncon(int a[10],int c[10],int b,int d[10],int e[10],int f[10]) {

	for(b=0;b<9;b++){
		a[b]= analogRead(c[b]); }
	for(b=0;b<9;b++) {
		a[b] = map(a[b], d[b],e[b], 0, 4095); }
    for(b=0;b<9;b++) {	
	a[b] = constrain(a[b], 0, 4095); }
	for(b=0;b<9;b++) {
		Tlc.set(f[b], a[b]); }
  }

  int blucon(int a[20],int c[20],int b,int d,int e,int f[20]) {
	
	
	for(b=0;b<20;b++){
		a[b]= analogRead(c[b]); }
	for(b=0;b<20;b++) {
		a[b] = map(a[b], d,e, 0, 255);}
	for(b=0;b<20;b++) {
		a[b] = constrain(a[b], 0, 255); }
	for(b=0;b<20;b++)
  Tlc.set(f[b], a[b]);
  }

/*
a=sensor pin
b= sensor value coresponding
c= array indicator
d= led pin
e= sensor min
f sensor max
*/
int calcups(int a,int b, int e, int f) {
	Tlc.init();
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
      //calibrate each sensor 5 seconds
  while (millis() < 5000) {
         b = analogRead(A7);
		 Tlc.set(0,1024);
    if (b > f) { // record max
          f = b; }
    if (b < e) { //record min val
          e = b;        }}
    digitalWrite(13, LOW);//end of cal
        }

int cCalcups(int a[10],int b[10], int e[10], int f[10]) {
Tlc.init();
int c;
	
	for(c=0;c<10;c++) {
	pinMode(a[c],INPUT);     
	}
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);

for(c=0;c<11;c++)
{ 	
	Tlc.set(c,1000);
	b[c] = analogRead(a[c]);
	delay(3500);
	Tlc.update();
          }
c=0;

for(c=0;c<9;c++) {
    if (b[c] > f[c])  // record max
	f[c] = b[c]; 
         }
c=0;
for(c=0;c<9;c++) {
    if (b[c] < e[c])  //record min val
	e[c] = b[c];  
          }
c=0;
	
	
	
 
digitalWrite(13, LOW);//end of cal
 }

#endif

yeah so thats just a normal libarry.

but yeah like i said just look at how ur using ur show() looks like a little mistake. i completely understand why that would work considering i know how a computer interputs. but that leads to problems just cause it compiles doesnt mean its write. see your LOGIC is right. its the implementation that needs fixing up. good route though good luck

sorry for tripple post but where you have

" void inarray::show() {} i understand what ur trying to do. but trying this. make sure ur libarry wrappers are in right like indef and endif and such etc. and take "intarray" out of void intarray::show(). just have void show() this way the class runs a function from with in the libarry itself and such. it may require a bit of switching things around but the effect will work. i would do all this for you now honestly but im tired as hell lmao.

i deal with these things ALL the time. im a software engineering/computer enginnering student at UH.

If you were a student in one of my classes, and you were spewing this nonsense, I'd flunk you.

hes using i and an indicator for a user defined set. it doesnt need to be specified. its common logic when dealing with things such.

What the heck is a "user defined set"? We're talking C++ here, where a term like that has absolutely no meaning.

classes dont need values. they refrence points.

Google translate may have failed you here.

its completely fine for i to be used.

I never said otherwise. What I said was that this:

int list[];

does not declare an array that can be dynamically sized. It declares an array with 0 elements. Any attempt to write to that array will overflow it.

anyway i use similar structure with "blank arrays"

When you do this:

    int ar[]={0,10,20};

you are asking the compiler to create an array big enough to hold all the values provided, and no bigger. The compiler is reasonable competent at parsing and counting, so the result is EXACTLY the same as if you had typed:

    int ar[3]={0,10,20};

which produces the exact same results as

    int ar[3];
     ar[0] = 0;
     ar[1] = 10;
     ar[2] = 20;

When the declaration and valuation of the array occur on the same line, the results are not necessarily the same as when the declaration and definition occur at different times.

In the definition of a class, the declaration and valuation of an array can not occur at the same time. So arrays must be explicitly sized. Implicit sizing, where the compiler figures out the size from the valuation data, is not possible. The compiler tries, but, since there are not values supplied (since it is not legal to supply them), it counts 0 supplied values (correctly, I might add) and sizes the array accordingly.

Now, go back and study some more. In the future, pay more attention in class.

One last question Is it possible of making a class whitch containes an array that is only declared AFTER the constructor,whitch gives the array a specified length (given by the argument),has run? It seems that the class need to know the length (to compile the program) of the array even before the constructor has run. Is there another way to do it without declaring a maximum length of the array? I got it to work (thank you for this) with a maximum length of 100 ints, but if i only use an array of 6 ints, the memory space for the other 94 are lost (can't be used for something else), right?

Knockstaart

Is it possible of making a class whitch containes an array that is only declared AFTER the constructor,whitch gives the array a specified length (given by the argument),has run?

Yes. I said this in an early reply.

In the header:

private:
int *somePointer;
int theSize;

public:
ClassName(int someSize);
~ClassName();
int getMethod(int someIndex);
void setMethod(int someIndex, int someValue);

In the source:

ClassName::ClassName(int someSize)
{
   theSize = someSize;
   somePointer = (int *)malloc(someSize * sizeof(int));
}

ClassName::~ClassName()
{
   if(somePointer)
      free(somePointer);
}

int ClassName::getMethod(int someIndex)
{
   if(somePointer && someIndex > 0 && someIndex <= theSize)
      return somePointer[someIndex];
   else
      return -999;
}

void ClassName::setMethod(int someIndex, int someValue)
{
   if(somePointer && someIndex > 0 && someIndex <= theSize)
      somePointer[someIndex] = someValue;
}

if i only use an array of 6 ints, the memory space for the other 94 are lost (can’t be used for something else), right?

They are not lost - they know where they are - but, yes, they can’t be used for any other purpose.

It seems that the class need to know the length (to compile the program) of the array even before the constructor has run. Is there another way to do it without declaring a maximum length of the array?

It depends on how ‘dynamic’ you want it to be. If you know the array sizes at compile time, but need different sized objects at different places, this might do

template< const int _Size > class AnySize{
  public:
    int &operator []( int i_Index ){ return this->i_MyArray[ i_Index ] };
    int &operator []( int i_Index ) const { return this->i_MyArray[ i_Index ] };
  protected:
  private:
    int i_MyArray[ _Size ];
};

//Allows

AnySize< 4 > a_4;     //Array of 4 elements

AnySize< 40 > a_40;  //Array of 40 elements

AnySize< 400 > a_400; //Array of 400 elements

Thank you This was really helpful

andrewmata24:
its common logic when dealing with things such. i deal with these things ALL the time. im a software engineering/computer enginnering student at UH.

In that case, please ask your tutor to look at your posts in this thread.