Error Code: Address of Stack Memory Passed as Variable

Probably allot of errors. Working through the code to print to the V5 Brain, Terminal, and *.dat file on computer. However I’m not understanding the problem with the returned array memory address…help asked for.

/*----------------------------------------------------------------------------*/
/*                                                                            */
/*    Module:       main.cpp                                                  */
/*    Author:       LoJac10                                                   */
/*    Created:      Wed Sep 25 2019                                           */
/*    Description:  Moving Forward (inches)                                   */
/*                                                                            */
/*    This program drives the robot forward for 6 inches. Additionally this   */
/*    program will print smartmotor encoder info to brain screen and a        */
/*    *.dat file on your computer.                                            */
/*                                                                            */
/*----------------------------------------------------------------------------*/

// ---- START VEXCODE CONFIGURED DEVICES ----
// Robot Configuration:
// [Name]               [Type]        [Port(s)]
// Drivetrain           drivetrain    1, 2, 19, 20 
// lfMotor              smartmotor    1
// lbMotor              smartmotor    2
// rfMotor              smartmotor    19
// rbMotor              smartmotor    20
// ---- END VEXCODE CONFIGURED DEVICES ----

#include "vex.h"
using namespace vex;


void resetDriveEncoders()
{
  lbMotor.setPosition(0, rotationUnits::raw);
  lfMotor.setPosition(0, rotationUnits::raw);
  rbMotor.setPosition(0, rotationUnits::raw);
  rfMotor.setPosition(0, rotationUnits::raw);
}

double *driveOffsetCal()
{
  // ** side diff **
  double leftsideDiff = lfMotor.position(rotationUnits::raw) - lbMotor.position(rotationUnits::raw);
  double rightsideDiff = rfMotor.position(rotationUnits::raw) - rbMotor.position(rotationUnits::raw);

  // ** cross diff **
  double frontcrossDiff = lfMotor.position(rotationUnits::raw) - rfMotor.position(rotationUnits::raw);
  double backcrossDiff = lbMotor.position(rotationUnits::raw) - rbMotor.position(rotationUnits::raw);

  double arr[4] = {leftsideDiff, rightsideDiff, frontcrossDiff, backcrossDiff};

  return arr;
}


int driveOffsetDisplay( )
{
  // pointer to returned array from driveOffsetCal
  double *ptr;

  // open 'output.dat' file to write to on computer
  std::ofstream output;
  output.open("output.dat");

  // pointer to variable
  ptr = driveOffsetCal();

  // clear screen to display encoder info
  Brain.Screen.clearScreen();

  // display some useful info on screen
  Brain.Screen.setCursor(2,1);

  // left-side encoder difference
  Brain.Screen.print( "  LSdiff: %4.0f", ptr[0] );
  Brain.Screen.newLine();
  std::cout << "LSdiff: " << ptr[0] << std::endl;
  
  // right-side encoder difference
  Brain.Screen.print( "  RSdiff: %4.0f", ptr[1] );
  Brain.Screen.newLine();
  std::cout << "RSdiff: " << ptr[1] << std::endl;
  
  // front motors encoder difference
  Brain.Screen.print( "  FCdiff: %4.0f", ptr[2] );
  Brain.Screen.newLine();
  std::cout << "FCdiff: " << ptr[2] << std::endl;

  // back motors encoder difference
  Brain.Screen.print( "  BCdiff: %4.0f", ptr[3] );    // print to brain
  Brain.Screen.newLine();                             
  std::cout << "BCdiff: " << ptr[3] << std::endl;     // print  to terminal

  Brain.Screen.newLine();

  // writes info to 'output.dat'
  output << "LeftSidediff: " << ptr[0] << std::endl;
  output << "RightSidediff: " << ptr[1] << std::endl;
  output << "FrontCrossdiff: " << ptr[2] << std::endl;
  output << "BackCrossdiff: " << ptr[3] << std::endl;

  // close 'output.dat' file
  output.close();

  // exit code
  return 0;

}


////////////////////////
//
// MAIN
//
/////////////////////////////////////////////////

int main() {
  // Initializing Robot Configuration. DO NOT REMOVE!
  vexcodeInit();

  resetDriveEncoders();
  driveOffsetDisplay( );
  Drivetrain.driveFor(forward, 6, inches);
  
  return 0;
}

A local variable created inside a function exists on the stack (the stack being an area of memory). Once the function returns the variable goes out of scope, that area of memory may be used by other code. Best to pass a pointer to an array and copy results into it.

4 Likes

Once again @jpearman “Thank you”.

I think this is a solution along the line you suggested.

/*----------------------------------------------------------------------------*/
/*                                                                            */
/*    Module:       main.cpp                                                  */
/*    Author:       LoJac10                                                   */
/*    Created:      Wed Sep 25 2019                                           */
/*    Description:  Moving Forward (inches)                                   */
/*                                                                            */
/*    This program drives the robot forward for 6 inches. Additionally this   */
/*    program will print smartmotor encoder info to brain screen and a        */
/*    *.dat file on your computer.                                            */
/*                                                                            */
/*----------------------------------------------------------------------------*/

// ---- START VEXCODE CONFIGURED DEVICES ----
// Robot Configuration:
// [Name]               [Type]        [Port(s)]
// Drivetrain           drivetrain    1, 2, 19, 20 
// lfMotor              smartmotor    1
// lbMotor              smartmotor    2
// rfMotor              smartmotor    19
// rbMotor              smartmotor    20
// ---- END VEXCODE CONFIGURED DEVICES ----

#include "vex.h"
using namespace vex;

// difference between V5 motor encoders
int leftsideDiff,
    rightsideDiff,
    frontcrossDiff,
    backcrossDiff;

// Initializing array elements
int arr[4] = {leftsideDiff, rightsideDiff, frontcrossDiff, backcrossDiff};

// assign array to pointer
int *ptr = arr;


void resetDriveEncoders()
{
  // left motors
  lfMotor.setPosition(0, rotationUnits::raw);
  lbMotor.setPosition(0, rotationUnits::raw);

  // right motors
  rfMotor.setPosition(0, rotationUnits::raw);
  rbMotor.setPosition(0, rotationUnits::raw);
  
}


void driveOffsetCal()
{
  // ** side diff **
  ptr[0] = lfMotor.position(rotationUnits::raw) - lbMotor.position(rotationUnits::raw);
  ptr[1] = rfMotor.position(rotationUnits::raw) - rbMotor.position(rotationUnits::raw);

  // ** cross diff **
  ptr[2] = lfMotor.position(rotationUnits::raw) - rfMotor.position(rotationUnits::raw);
  ptr[3] = lbMotor.position(rotationUnits::raw) - rbMotor.position(rotationUnits::raw);
}


void prepBrainScreen()
{
  // clear screen to display info
  Brain.Screen.clearScreen();

  // display some useful info on screen
  Brain.Screen.setCursor(2,1);
}

/**
  * DESCRIPTION: display encoder info to V5 Brain
  *
  */
int driveOffsetDisplay_Brain()
{
  // left-side encoder difference
  Brain.Screen.print( "LSdiff: %4.0f ", ptr[0] );  
  Brain.Screen.newLine();  

  // right-side encoder difference
  Brain.Screen.print( "RSdiff: %4.0f ", ptr[1] );
  Brain.Screen.newLine();

  // front motors encoder difference
  Brain.Screen.print( "FCdiff: %4.0f ", ptr[2] );
  Brain.Screen.newLine();

  // back motors encoder difference
  Brain.Screen.print( "BCdiff: %4.0f ", ptr[3] );    
  Brain.Screen.newLine();  

  // new line for spacing
  Brain.Screen.newLine();
  // new line for spacing
  Brain.Screen.newLine();

  return 0;
}

/**
  * DESCRIPTION: display encoder info to VEXcode Pro Terminal
  *
  */
int drivesetDisplay_Terminal()
{
  // left-side encoder difference
  printf("LSdiff: %d \n", ptr[0]);

  // right-side encoder difference
  printf("RSdiff: %d \n", ptr[1]); 

 // front motors encoder difference
  printf("FCdiff: %d \n", ptr[2]); 

  // back motors encoder difference  
  printf("BCdiff: %d \n", ptr[3]); 

  // print newline for spacing
  printf("\n");

  return 0;

}


/**
  * DESCRIPTION: write encoder info to *.dat file
  * !!! WORK IN PROGRESS !!!
  */
int drivesetDisplay_Dat()
{
  // open 'output.dat' file to write to on computer
  std::ofstream output;
  output.open("output.dat");

  // left-side encoder difference
  output << "LeftSidediff: "   << ptr[0] << std::endl; 

  // right-side encoder difference    
  output << "RightSidediff: "  << ptr[1] << std::endl;

  // front motors encoder difference
  output << "FrontCrossdiff: " << ptr[2] << std::endl;
  
  // back motors encoder difference  
  output << "BackCrossdiff: "  << ptr[3] << std::endl;

  // close 'output.dat' file
  output.close();

  return 0;

}



////////////////////////
//
// MAIN
//
/////////////////////////////////////////////////

int main() {
  // Initializing Robot Configuration. DO NOT REMOVE!
  vexcodeInit();
  prepBrainScreen();

  resetDriveEncoders();
  driveOffsetDisplay_Brain();
  drivesetDisplay_Terminal();
  drivesetDisplay_Dat();
  Drivetrain.driveFor(forward, 6, inches);

  driveOffsetCal();
  driveOffsetDisplay_Brain();
  drivesetDisplay_Terminal();
  drivesetDisplay_Dat();

  return 0;
}

That will work, however, as you made the array global you didn’t really need the intermediate pointer at all. I was thinking more of this.

// pArray is a 4 element array
void driveOffsetCal( int pArray[] )
{
  // ** side diff **
  pArray[0] = lfMotor.position(rotationUnits::raw) - lbMotor.position(rotationUnits::raw);
  pArray[1] = rfMotor.position(rotationUnits::raw) - rbMotor.position(rotationUnits::raw);

  // ** cross diff **
  pArray[2] = lfMotor.position(rotationUnits::raw) - rfMotor.position(rotationUnits::raw);
  pArray[3] = lbMotor.position(rotationUnits::raw) - rbMotor.position(rotationUnits::raw);
}

int main() {
  int  arr[4];

  driveOffsetCal( arr );
  // now we can use values in arr

}

In C++ (using std::vector etc.) there are fancier ways of doing this that stop you making mistakes like creating buffer overflows.

4 Likes

so much wrong.

display.pBrain = driveOffsetDisplay_Brain();

This assigns result of calling driveOffsetDisplay_Brain to display.pBrain, I suspect you wanted address of driveOffsetDisplay_Brain.

display.pBrain;

?? That’s just a variable, you don’t do anything with it.
If you wanted to call a function, look into making pBrain a pointer.
but it seems way over complicated.

3 Likes

ok. thank you. will go back to drawing board.