Array只保留返回最后一个元素。 [C /阿尔杜伊诺]

时间:2014-07-09 12:55:08

标签: c++ c arrays pointers arduino

我在Arduino上的数组(称为"输入"类型" GeneralInput")存在问题,基本上,无论我尝试访问哪个元素,代码总是返回该数组的最后一个元素。 这是代码的一部分:

//...include statements
//other initializations
GeneralInput *Inputs[19];

void setup() 
{
    //...
    //...
    InitializeInputs();
}

void InitializeInputs()
{
    //type 0 = pedal switch;  1 = volume pedal
    //type 2 = potentiometer;   3= switch;
    //pedal switches
    Inputs[0] = &GeneralInput(0,0,true,false,NULL,10);
    Inputs[1] = &GeneralInput(1,0,true,false,NULL,9);
    Inputs[2] = &GeneralInput(2,0,true,false,NULL,6);
    Inputs[3] = &GeneralInput(3,0,true,false,NULL,5);
    //volume pedal
    Inputs[4] = &GeneralInput(4,1,false,false,NULL,A2);
    //potentiometer
    Inputs[5] = &GeneralInput(5,2,false,true,mux2,5);
    Inputs[6] = &GeneralInput(6,2,false,true,mux2,6);
    Inputs[7] = &GeneralInput(7,2,false,true,mux2,7);
    Inputs[8] = &GeneralInput(8,2,false,true,mux2,8);
    Inputs[9] = &GeneralInput(9,2,false,true,mux2,9);
    Inputs[10] = &GeneralInput(10,2,false,true,mux2,10);
    Inputs[11] = &GeneralInput(11,2,false,true,mux2,11);
    //switch
    Inputs[12] = &GeneralInput(12,3,true,true,mux2,15);
    Inputs[13] = &GeneralInput(13,3,true,true,mux2,14);
    Inputs[14] = &GeneralInput(14,3,true,true,mux2,13);
    Inputs[15] = &GeneralInput(15,3,true,true,mux2,12);
    //joystick   
    Inputs[16] = &GeneralInput(16,3,true,true,mux1,2);  //switch
    Inputs[17] = &GeneralInput(17,2,false,true,mux1,1); //x axis
    Inputs[18] = &GeneralInput(18,2,false,true,mux1,3); //y axis
}

void loop() 
{  
    int length=0;
    //cycle through different inputs
    int startIndex=0,endIndex=0;
    //temp arrays
    byte toSendTmp[30]; 
    for(int i=0;i<30;i++)
      toSendTmp[i]=0;
    //...
    //..
    int packetIndex=0;
    for(int i=startIndex;i<endIndex;i++)
    {
         //if the input is updated,fill the array with the new data
         /*
          * When i try to have access to the i-element i always get
          * the last one instead.
          */
         if(Inputs[i]->Update())
         {
            toSendTmp[(packetIndex*3)] = Inputs[i]->GetID(); 
            toSendTmp[(packetIndex*3)+1] = Inputs[i]->GetType(); 
            toSendTmp[(packetIndex*3)+2] = Inputs[i]->GetValue();
            packetIndex++;
         }         
    }
    //....
    //...
}

如果需要GeneralInput.hGeneralInput.cp p代码。 注意:我无法判断数组是否总是返回最后一项,或者数组的每个插槽是否都填充了指向同一对象(最后创建的)的指针。

对我做错了什么的想法?

提前致谢。

3 个答案:

答案 0 :(得分:1)

您的&GeneralInput不正确,实际上您创建临时对象并将其地址存储在数组中,但只要您的GeneralInput对象被破坏(与创建相同的行),就会生成一个新对象放在同一地址:

// Create GeneralInput at address @
Inputs[0] = &GeneralInput(0,0,true,false,NULL,10);
// End of your temporary object, the `GeneralInput` object is destroyed but you still
// points to its address...
/* etc. */

您获取最后一个值是因为编译器始终在同一地址创建GeneralInput,因此所有Inputs[]都指向同一地址。

您需要动态创建GeneralInput

Inputs[0] = new GeneralInput(0,0,true,false,NULL,10);

答案 1 :(得分:0)

数组中的每个插槽都有一个指向同一内存位置的指针,该位置由您创建的最后一个元素占用。通过执行&GeneralInput(...),您将在堆栈上创建一个GeneralInput对象并检索其堆栈地址。但由于GeneralInput对象本身从未分配给变量,因此它占用的内存可立即重用。这意味着每个GeneralInput对象都在堆栈的同一地址创建。但是,解决方案并不是将代码更改为

GeneralInput genInput = GeneralInput(...);
Inputs[...] = &genInput;

这样的代码仍将用指向堆栈地址的指针填充数组。当函数返回时,这些指针将立即变为无效。你应该用

之类的东西填充数组
Inputs[...]  = (GeneralInput*)malloc(sizeof(GeneralInput));
*Inputs[...] = GeneralInput(...);

使用此方法,请确保如果您的Inputs数组到达不再使用它的点,则free每个元素都会循环。

编辑:Arduino使用C,所以没有new。请改用mallocfree

答案 2 :(得分:0)

正如其他人所说,问题在于临时变量的地址。你可以绕过&#34; new&#34;有默认参数的问题。

class GeneralInput
{
public:
    GeneralInput(int a = 0, int b = 0, bool c = true, bool d = true, int* e = NULL, int f = 0);
    ...
};

然后声明你的数组 - 这需要使用默认参数

的GeneralInput
GeneralInput inputs[20];

然后在初始化中 - 然后你不会遇到新问题或临时问题在例程结束时消失。

void InitializeInputs()
{
    inputs[0] = GeneralInput(0,0,true,false,NULL,10);
    ...
}

我不知道NULL指向的是什么,但如果除了复制值之外的任何其他内容,您可能想要为此设置复制操作符。效率不高,因为它调用构造函数两次,但只在初始化时发生。