Corrupt data on fifth parameter in a method?

Hey all, I've got a class with around 12 member variables, and I've noticed that when I write a function to set all these variables at once, some of the data becomes corrupt. For example.

 drinks[0].setDrink(4,0,0,5,0,3,1,0,0, "test2.bmp");//This works fine, only 4 parameters are passed through.(integers, that is)
 drinks[1].setDrink(2,2,2,2,2,0,0,0,0, "test.bmp");//this breaks something, and one of the values I set goes to 28418. In this case it was the fourth parameter that went to 28418.

If I break that function up into two smaller functions, no problem. i.e;

  drinks[1].altSetDrink1(1,1,1,1);
  drinks[1].altSetDrink2(1,1,1,1);//These two methods each set half of the member variables. Everything works fine here.

Can somebody possibly explain what's going on here please? I'm quite baffled and I've never run into this before.

Thanks much!~

Hi,
You might be running out of stack, does your program use a lot of memory ?

Duane.

drinks[0].setDrink(4,0,0,5,0,3,1,0,0, "test2.bmp");//This works fine, only 4 parameters are passed through.(integers, that is)

Strictly speaking, "4 parameters are passed" referred to this call is obviously wrong. You pass it 10 parameters. Maybe you mean that only the first four are used inside the function ?

Can you post the setDrink code ? Thank you.

Can somebody possibly explain what's going on here please?

Without seeing your code? No.

Sorry about not posting the method, I thought I had.

  void Drink::setDrink(int vodka, int rum, int orangeJuice, int cocaCola, int sprite ,int bs1, int bs2, int ozSize, int cost, char* bmpName){
     this->_vodka = vodka;
     this->_rum = rum;
     this->_orangeJuice = orangeJuice;
     this->_cocaCola = cocaCola;
     this->_sprite = sprite;
     this->_ozSize = ozSize;
     this->_cost = cost;
     this->_bs1 = bs1;
     this->_bs2 = bs2;
     strcpy(this->_bmpName, bmpName);
   }

mromani:

drinks[0].setDrink(4,0,0,5,0,3,1,0,0, "test2.bmp");//This works fine, only 4 parameters are passed through.(integers, that is)

Strictly speaking, "4 parameters are passed" referred to this call is obviously wrong. You pass it 10 parameters. Maybe you mean that only the first four are used inside the function ?

Can you post the setDrink code ? Thank you.

Yes you're absolutely right there are 10 parameters. I did indeed mean if any more than 4 of the integer parameters are set to be non-zero it corrupts the fifth one.

I'm curious about the use of ints. I can't imagine a drink that calls for more than 255 parts of anything. Is there one in your catalog?

The this-> on every line is not needed.

Actually I hadn't really considered any other variable type than integer. Yeah I know the this-> is unnecessary but I gave it a shot to see if it would un-corrupt the values.

I suppose you're referring to BYTE as the datatype? I've never really worked with it before. I could just switch all the INTs to BYTES and that would cut memory usage by about half I suppose. Thanks =D

Any idea why the values are corrupting?

I suppose you're referring to BYTE as the datatype?

Actually, byte, not BYTE.

I could just switch all the INTs to BYTES and that would cut memory usage by about half I suppose.

Each entry consists of 9 values plus some characters. The 9 values currently take 18 bytes. You would save 9 bytes per drink entry.

Any idea why the values are corrupting?

I suspect that the stack corruption suggestion was probably correct. What board are you using?

I'm presently using the newest revision of the UNO, and I have a mega which I will eventually move the project to.

if any more than 4 of the integer parameters are set to be non-zero it corrupts the fifth one.

I’m sorry but I still don’t get it. What do you mean by “it corrupts the fifth one” ? How do you detect the parameter corruption ?

Well before it enters the dispensing function, I have it print the values of all the member variables to the console.

It ends up looking something like this

Vodka: 1 Rum: 1 OJ: 1 Coke: 1 Sprite:28174

and then when it goes into the sprite dispenser it loops.....well 28174 times. I

I think the stack space exhaustion suggestion might be correct. More could be said by looking at the entire code (if you can publish it). In the meantime, I suggest you try to replace that long list of parameters with a struct, and pass it by reference rather than by value. This would require just sizeof(pointer) bytes, which is two bytes.

HTH

Changing my code bytes instead of INTs has removed the problem, but when I increase the amount of variables I’m sure it’s going to corrupt again. Could you possibly give me an example of how to write those into a struct and pass it as a reference.

I would just pass &structName to the setDrink function? Would I declare the struct globally or within the Drink class? A tiny example would really help me understand what you’re getting at.

This is my first time programming on an arduino and I’ve never had to really consider physical limitations before.

Prototype in the header

   void setDrink(byte vodka, byte rum, byte orangeJuice, byte cocaCola, byte sprite, byte bs1, byte bs2, byte ozSize, byte cost, char* name);

Implementation

   void Drink::setDrink(byte vodka, byte rum, byte orangeJuice, byte cocaCola, byte sprite ,byte bs1, byte bs2, byte ozSize, byte cost, char* bmpName){
     _vodka = vodka;
     _rum = rum;
     _orangeJuice = orangeJuice;
     _cocaCola = cocaCola;
     _sprite = sprite;
     _ozSize = ozSize;
     _cost = cost;
     _bs1 = bs1;
     _bs2 = bs2;
     strcpy(this->_bmpName, bmpName);
   }

Construction and setting Calls

#include "Constants.h"
#include "drinks.h"
#include <string.h>
#include <Servo.h>
#include "Mixer.h"
#include <String.h>

Drink drinks[3];

void setup(){
  
  drinks[0].setDrink(4,0,2,5,0,3,1,0,0, "Vodka.bmp");
  drinks[1].setDrink(1,1,1,1,1,1,1,1,1,"testing2.bmp"); //These all work fine now that I've changed them to bytes but I would like to make it safer.
  drinks[2].setDrink(2,2,2,2,2,0,0,0,0, "ScrewDriver.bmp");
}

If you could just write up something quick and easy for passing the struct by reference and where to define it, that would be great.

Thanks for your time.

Ok, here’s a quick example (compiled and run).

StructVsFunctionsTest.ino (525 Bytes)

Drink.h (610 Bytes)

Drink.cpp (768 Bytes)

Util.h (411 Bytes)

Duplicating the drinkRecipe into the Drink seems like it’s just wasting space. Why not construct each Drink in place?
Pass in the values you need in the constructor. Initialize the array of drinks in place. Done!

Tadgh: ...

     strcpy(this->_bmpName, bmpName);

...

Corruption, and then this. I'm deeply suspicious when I see strcpy without supporting code to show that you have allocated space for it.

jwatte: Duplicating the drinkRecipe into the Drink seems like it's just wasting space. Why not construct each Drink in place? Pass in the values you need in the constructor. Initialize the array of drinks in place. Done!

Passing them directly into the constructor gave me the same problem unfortunately.

mromani: Ok, here's a quick example (compiled and run).

Thank you muchly, I've never done object-oriented programming before and didn't realize you could declare structs inside class files. For some reason I thought you could only declare the class in it.

Passing them directly into the constructor gave me the same problem unfortunately.

You didn’t address the second of Nick’s observations (and, quite likely the cause of your problems).

PaulS:

Passing them directly into the constructor gave me the same problem unfortunately.

You didn't address the second of Nick's observations (and, quite likely the cause of your problems).

Did you mean Nick or Jwatte? I removed the string from the class and the setter just for testing and had the same problem as well. However, setting them all in a struct and passing them through seems to work just fine.