2014-07-09 2 views
1

Arduino에서 배열에 문제가 있습니다 (기본적으로 "GeneralInput"유형의 "Inputs"라고 함). 액세스 할 수있는 요소가 무엇이든 관계없이 코드에서 항상 마지막 요소를 반환합니다. 그 배열의. 다음은 코드의 일부 :배열은 마지막 요소 만 계속 반환합니다. [C/Arduino]

//...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

+4

나는 이것이 컴파일하는 것에 놀랐습니다. 임시 오브젝트의 주소는 가져올 수 없습니다. –

+0

Arduino에서 'new'를 사용할 수 없으므로 고맙습니다. 맞습니다. 문제를 살펴 보겠습니다. – MTKJacob

+0

@JosephMansfield C에서 무엇에 관한 주소 (예 :'char ** foo = &"bar";')가 "취할 수"있습니다. 그러나 로컬 변수와 같이 일반적으로 처리되지 않는 무언가의 주소를 취하는 것이 유용 할 수있는 상황은 제한적입니다. –

답변

0

배열의 모든 슬롯이 생성 마지막 요소에 의해 점유되는 동일한 메모리 위치에 대한 포인터를 가지고있다. &GeneralInput(...)을 수행하면 스택에 GeneralInput 객체가 만들어지고 스택 주소가 검색됩니다. 그러나 GeneralInput 객체 자체는 변수에 할당되지 않으므로이 객체가 차지하는 메모리를 즉시 재사용 할 수 있습니다. 즉, 모든 GeneralInput 객체가 스택의 같은 주소에 만들어집니다. 그러나 해결책은 코드를 다음과 같이 변경하지 않는 것입니다.

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

코드는 여전히 스택 주소에 대한 포인터로 배열을 채 웁니다. 이러한 포인터는 함수가 반환 될 때 즉시 무효화됩니다. 당신은이 방법을 사용

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

같은 것을 사용하여 배열을 작성해야 확실하게 당신의 Inputs 배열 이제까지 당신이 모든 요소를 ​​보내고 그 free을 통해 더 이상 루프를 사용하지 않는 지점에 도달합니다.

편집 : Arduino는 C를 사용하므로 new이 없습니다. 대신 mallocfree을 사용하십시오.

+0

답변 주셔서 감사합니다, 세부 사항을 주셔서 감사합니다, 불행히도 나는 arduino에 "새"를 사용할 수 없습니다. – MTKJacob

+0

아 맞습니다. 여전히 포인터 배열을 사용하려는 경우에 대비하여 내 대답을 편집합니다. –

+0

고마워, 나는 여전히 ""같은 ""을 가지고 있지만, 지금은 또 다른 이유라고 생각한다. 아마도 GeneralInput 클래스의 데이터는 자신의 객체와 관련되지 않고 정적 멤버로 계속 덮어 쓰게됩니다. – MTKJacob

1

사실 임시 개체를 만들고 배열에서 자신의 adresses를 저장하지만, 곧 당신의 GeneralInput 개체를 얻을으로, 새로운 객체가 동일한 주소에서 발생 (생성과 동일 라인) 파괴, 잘못된 :

컴파일러는 항상 같은 주소에 같은 주소로하여 모든 Inputs[] 점을 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[0] = new GeneralInput(0,0,true,false,NULL,10); 
+0

고마워, 네 말이 맞아, 문제는 Arduino에서 "새로운"키보드를 사용할 수 없기 때문에 해결 방법을 찾아야한다는 것이다. 다시 감사 드린다. – MTKJacob

+0

@MTKJacob 정말 포인터를 사용해야합니까? – Holt

0

다른 사람들이 말했듯이 문제는 임시 변수의 주소와 관련이 있습니다. 기본 매개 변수를 사용하여 "새로운"문제를 해결할 수 있습니다.

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

그런 다음 배열을 선언 - 당신은 새로운 문제 또는의 끝에서 사라지는 임시 변수의 문제가되지 않습니다 -이 다음 초기화의 기본 매개 변수

GeneralInput inputs[20]; 

와 GeneralInput 소요 루틴.

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

NULL이 무엇인지는 모르지만이 값을 복사하는 것 이외의 다른 것이라면 복사 연산자에 넣을 수 있습니다. 생성자를 두 번 호출하지만 초기화시에만 발생하기 때문에 그리 효율적이지 않습니다.

관련 문제