Confusion with memset and pointers

Hi all, sorry if this is noobish question. I thought I had a handle on pointers and apparently I do not. The purpose of this code is to take a character array from a serial input and format it to be useful. The whole code is posted at the end.

Where I am confused…
if I have something like–

char VIn[20]; //value from serial ~ “Pa .1234e1 pa\n” gets written to it

//and I use memset/copy to do some formatting
memset(&VIn+(strln-3), 0, 3); //trims last 3 values IE " pa" (start, value, width)
memcpy(&VIn,VIn+4,16); //Overwrites first 4 characters "Pa: " (dest, source, width)

//The above works while the following doesn’t, and I don’t understand why.

memset(&VIn+(strln-3), 0, 3); //trims last 3 values IE " Pa" (start, value, width)
memcpy(&VIn,&VIn+4,16); //Overwrites first 4 characters "Pa: " (dest, source, width)

I don’t understand why I wouldn’t use an & for the source in memcpy, if i do I get junk. The code I’m using works fine, but I’d like to understand what I’m doing. Can someone fill in my lack of understanding.

also, In the real program I’m using tft.print() to monitor the values, and they are proper, while Serial.print() does bad things, even after dtostrf().

void GetVac(){ 
  char VIn[20];
  memset(&VIn, 0, 20);
  int strln;

  Serial1.write("P"); Serial1.write('\r'); //requests vac
  delay(10);
  
  if(Serial.available()){
    
    strln = Serial.readBytesUntil('\r', VIn, 20);     //reads until carriage return into array (max 20 chracters) ex: "Pa:  1.234e0  pa\n"
    
    while (Serial.available() > 0) {Serial.read();} //clears buffer if extra data
 
    memset(&VIn+(strln-3), 0, 3);      //trims last 3 values IE " Pa" (start, value, width)  -MUST SET RIGHT FOR /BR  or else "e-1000"
    memcpy(&VIn,VIn+4,16);             //Overwrites first 4 characters "Pa: " (dest, source, width) 
    
    
    Serial.println(atof(VIn));
    
    if ( atof(VIn) > .001 && atof(VIn) < 9999 ){  //only updates values if not garbage
      Vac.Float = atof(VIn);                      //converts string VIn to float-> vac.float
      dtostrf(Vac.Float ,6, 3, Vac.Char);         //converts vac.float to vac.string, (source, length, decimals, output)
      memset(&Vac.Char+6, 0, 10);                  //and turns string to 6 chars (sets +6 to zeros)  .Char is [16]
      Serial.println(Vac.Char);
      
    }
  
  }
  if (Vac.Float <.2) {SysState.VacReady=1;}  //needs to be outside of loop for ends of run
  else {SysState.VacReady = 0;}
  
}

Gliscameria:

char VIn[20];  //value from serial ~ "Pa  .1234e1 pa\n" gets written to it

strln = Serial.readBytesUntil(’\r’, VIn, 20);

memset(&VIn+(strln-3), 0, 3);      //trims last 3 values IE " pa" (start, value, width) 
memcpy(&VIn,VIn+4,16);            //Overwrites first 4 characters "Pa: " (dest, source, width)

VIn is already a pointer. Doing pointer arithmetic (badly) does not automatically dereference the pointer so there is no need for the address of operator & in either the memset or memcpy.

Be aware too that, if strln is less than 3, you could overwrite data that is in front of your buffer (probably corrupting the stack).

Thank you! That makes sense, and makes me realize I still have no idea how pointers work. I’ll pull the &s out.

Thanks for catching the strln bug. The only ‘fix’ I can think of is to make an if statement to keep it at 3+.

So is VIn a pointer because i had not assigned any vales to the array? Sorry for the followup, but I’d like to understand where to use these a bit better, and reading through examples isn’t helping me , obviously. I have code that ‘works’ either way, but I’d like to do things properly.

I also have–

struct VacStruct {
float Float = 999999;
char Char[16];
} Vac;

should I use address operator in any of these?

Vac.Float = atof(VIn);
dtostrf(Vac.Float ,6, 3, Vac.Char);
memset(Vac.Char+6, 0, 10);

You also should be using memmove(), not memcpy(). memcpy() does not guarantee the direction it will copy from the source to the destination, and it may copy more than one byte at a time, both of which may give you unexpected results.

Gliscameria:
So is VIn a pointer because i had not assigned any vales to the array?

No, VIn is a pointer to a memory location irrespective of what is stored in that (and following) memory location(s).
Loosely speaking, an array is just pointer with some memory to point to.

Gliscameria:
I also have--

struct VacStruct {
float Float = 999999;
char Char[16];
} Vac;

should I use address operator in any of these?

Vac.Float = atof(VIn);
dtostrf(Vac.Float ,6, 3, Vac.Char);
memset(Vac.Char+6, 0, 10);

No.

Gliscameria:
char VIn[20]; //value from serial ~ "Pa .1234e1 pa\n" gets written to it

memset(&VIn+(strln-3), 0, 3); //trims last 3 values IE " pa" (start, value, width)

This shouldn't compile at all. Specifically, '&VIn' is not an expression that can be evaluated AFAIK.

When an array identifier is used in an expression, the evaluated value of that identifier is "pointer to the zeroth element of the array".