簡體   English   中英

數組僅返回最后一個元素。 [C /阿爾杜伊諾]

[英]Array keeps returning only the last element. [C/Arduino]

我在Arduino上遇到一個數組(稱為“ GeneralInput”類型的“ Inputs”)問題,基本上,無論我嘗試訪問哪個元素,代碼始終會向我返回該數組的最后一個元素。 這是代碼的一部分:

//...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代碼。 注意:我無法確定數組是否總是返回最后一個項目,或者數組的每個插槽是否都填充有指向同一對象(最后創建的對象)的指針。

我做錯了什么主意嗎?

提前致謝。

您的&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);

數組中的每個插槽都有一個指向相同存儲位置的指針,該位置就是您創建的最后一個元素所占用的位置。 通過執行&GeneralInput(...)您將在堆棧上創建GeneralInput對象並檢索其堆棧地址。 但是,由於GeneralInput對象本身從未分配給變量,因此它占用的內存可立即用於重用。 這意味着每個GeneralInput對象都在堆棧上的相同地址處創建。 但是,解決方案不是將您的代碼更改為類似

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

這樣的代碼仍將使用指向堆棧地址的指針填充數組。 當函數返回時,這些指針將立即變為無效。 你應該用類似的東西填充數組

Inputs[...]  = (GeneralInput*)malloc(sizeof(GeneralInput));
*Inputs[...] = GeneralInput(...);

使用此方法,請確保如果Inputs數組達到了不再使用的位置,則在該數組上循環以free每個元素。

編輯:Arduino使用C,所以沒有new 使用mallocfree代替。

正如其他人所說,問題出在臨時變量的地址上。 您可以通過使用默認參數來解決“新”問題。

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];

然后在Initialize(初始化)中,您將不會遇到新的問題,也不會在例程結束時臨時出現問題。

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

我不知道NULL指向什么,但是如果它不是復制值,則可能需要為此使用復制操作符。 效率不高,因為它兩次調用構造函數,但這僅在初始化時發生。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM