Pointer confusion

I’ve been trying to receive whole arrays via serial communication, and have been trying to make use of pointers. Below is my cpp file.

/*

#include <Arduino.h>
#include "BreathSim.h"

BreathSim::BreathSim()
{
}
char BreathSim::checkstate(char state)
{
  char aChar = Serial.read();
    if (aChar == '<')
    {
        return 1;
    }
    else if (aChar=='>')
    {
        return 2
    }
    else
    {
        return state;
    }
}

void BreathSim::GetChar(int index)
{
    char inData[10];
    
    char aChar = Serial.read();
        inData[index] = aChar;
        inData[index+1] = '\0';
}

void BreathSim::ToInt(int index, int *Array, char inData)
{
    int inInt = atoi(inData);
    *(Array+index) = inInt;
    *(Array+index+1) = '\0';
    
}

void BreathSim::Step(int N, int T) {
    int n = 0;
    while (n < N)
    {
        PORTD = PORTD || 0x10;
        delay(int(T / 2));
        PORTD = PORTD && 0xEF;
        delay(int(T / 2));
        n = n + 1;   // record this step
    }
}

void BreathSim::Signal()
{
    Serial.println('a');
    char a = 'b';
    while (a != 'a')
    {
        a = Serial.read();
    }
}

And my main

#include <BreathSim.h>


int *Profile;
char state = 0; // 1 for started 2 for ended
int i = 0;
int ProfileIndex = 0;
char inData;


BreathSim breathsim;
void setup()
{
  Serial.begin(115200);
  DDRD = DDRD || 0xFC;
  PORTD = 0x00;
  breathsim.Signal();
}


void serialEvent()
{
  if (Serial.available())
  {
    state == breathsim.checkstate(state);
    if (state == 1)
    {
      breathsim.GetChar(i, inData);
      i++;
     
    }
    if (state == 2)
    {
      i = 0;
      breathsim.ToInt(ProfileIndex, *Profile, inData);
      ProfileIndex++;
      breathsim.Signal();
    }
  }
}

void loop()
{
  if (ProfileIndex > 250)
  {
    digitalWrite(5, HIGH);
    for (int j = 0; j <= ProfileIndex; j++)
    {
      breathsim.Step(1, *(Profile+j));
    }
  }
}

The issue I am having is in the line

breathsim.ToInt(ProfileIndex, *Profile, inData);

Where I get an error that I am converting from int to int*, I am a little confused as to why as I’m not sure where the int type is coming from, I thought I was just working with the pointer.

Any help would be much appreciated.

What happens if you change this:

breathsim.ToInt(ProfileIndex, *Profile, inData);

to this:

breathsim.ToInt(ProfileIndex, Profile, inData);

In compiler terms, the lvalue of a variable is where it lives in memory and the rvalue is what is contained at that memory address. For "normal" variables, the rvalue is the value assigned to that variable. For a pointer, however, the rvalue of a valid pointer can only be a memory address or null (i.e., a non-valid pointer). The signature of the ToInt() method expects to receive an int pointer. Instead you are sending the content of the pointer, which is a memory address. So you are "double indirecting" off the pointer because you are sending the rvalue for the call instead of the lvalue.

This is a common mistake, so let's walk through an example:

void setup() {
  Serial.begin(9600);
  int x;
  int *ptr;

  x = 10;
  ptr = &x;
  Serial.print("x = ");
  Serial.print(x);
  Serial.print("   ptr = ");
  Serial.println(*ptr);

  x = AFunction(ptr);
  Serial.print("x = ");
  Serial.print(x);
}

int AFunction(int *val)
{
  Serial.print("In function, val = ");
  Serial.println((unsigned int) val);
  return *val + *val;
}
void loop() {
}

Suppose x ends up at memory address 500 and ptr lives at address 900. The lvalue of x is 500 and the rvalue is 10. The last line causes the value 500 (x's lvalue) to be placed at memory address 900. That is, the lvalue of ptr is 900 and its rvalue is 500. Now suppose you have the following function:

int AFunction(int *val)
{
   return *val + *val;
}

Because the function expects an int pointer, the function knows it is receiving a memory address, in this case the lvalue of x since we initialized ptr to point to x. The code then uses indirection (i.e., the *val expressions) to fetch the rvalues and add them together. The end result is x now equals 20.

Now, what happens if you do this:

x = AFunction(*ptr);

Now the code won't compile because you are passing the memory address of x rather than the memory address of ptr; the signature of the AFunction() function doesn't match what you are trying to pass to it. If the compiler let you do that, you would end up with a garbage value for x.

Take some time with this example, add a few more prints and see if you can actually see what's going on.

econjack:

Thank you this was very well explained, I managed to dig through and find a couple of places where I had misunderstood pointers in my code with the help of your explanation.