2013-12-07 2 views
2

나는 C를 배우고 동적 배열을 작성하려고합니다. 이것에 대한 훌륭한 튜토리얼을 발견했지만 모든 것을 얻지는 못합니다. 내가 가진 코드는 지금은 배열에 3 요소를 추가 할 수 있지만 그것은 단지 2에 할당하지만 인쇄 할 때 그것을 잘 작동 내 주요 기능에C 동적 배열 요소 액세스

typedef struct{ 
    int size; 
    int capacity; 
    char *data; 
}Brry; 

void brry_init(Brry *brry){ 
    brry->size = 0; 
    brry->capacity = 2; 
    brry->data = (char *)calloc(brry->capacity, sizeof(char)); 
} 

void brry_insert(Brry *brry, char value){ 
     brry->data[brry->size++] = value; //so do check here if I have enough memory, but checking something out 
} 

int main(void){ 
    Brry brry; 
    brry_init(&brry); 

    for (int i = 0; i < 3; i++) { 
     brry_insert(&brry, 'a'); 
    } 

    printf("%c\n", brry.data[2]); 
    return 0; 
} 

입니까? 나는 이상한 가치가 인쇄되기를 기대했다. 왜 이것이 아니면 내가 뭔가 잘못하고있는 걸까요?

+1

'brry.data [3]'은 네 번째 요소입니다. – Novak

+0

죄송합니다 실수를 복사 – Haagenti

+0

이것은 [정의되지 않은 동작] (http://stackoverflow.com/a/367662/1113392) – A4L

답변

3

메모리를 충분히 할당하지 않은 버퍼에 쓰려고합니다. 작동한다는 것은 보장되지 않습니다.

당신이 지금 시도하고있는 것은 메모리에서의 어떤 쓰레기 값을 읽는 것입니다. 누가 알고 있는가, 때때로 세그먼테이션 결함으로 이어지고 운이 좋으면 어떤 쓰레기 값을 얻을 수 있으며 세그 폴트는 아닙니다.

정크 메모리에 기록하면 정의되지 않은 동작이 발생하므로 잘보아야합니다. 오류가 발생하면 거의 항상 세그 폴트 (Segfault)가되어 세그먼트 화 오류가 발생합니다. 위로 읽으십시오 here.

배열의 경계를 넘어서 읽음으로써 수행하고있는 작업에 대한 기술을 포인터의 derefencing이라고합니다. 또한 here에 대해 자세히 알아볼 수도 있습니다.

+0

잘못되었습니다. 운이 좋다면 seg 오류가 발생하고 "현재 작동 중"대신에 뽑아서 길 아래에있는 사람에게 수백만 달러의 잠재적 인 오류가 발생할 수있는 치명적인 오류가 발생했는지 확인하십시오. 분실 된 임금으로 인한 손해 배상, 수리/재 설계 비용 등. – ciphermagi

+0

@JonahNelson 예, 때때로 운이 좋을 것입니다. 하지만 OP가 뭔가를 배우기를 바랍니다. – edwardmp

1

예, 실제로 두 요소 배열의 세 번째 요소에 쓰고 있습니다. 즉, 프로그램이 정의되지 않은 동작을 나타내며 어떤 일이 발생할 지 보증 할 수 없습니다. 귀하의 경우 운이 좋았고 프로그램은 "효과가 있었지만"항상 운이 좋은 것은 아닙니다.

1

배열의 끝에서 읽기/쓰기를 시도하면 정의되지 않은 동작이 발생합니다. 정확하게 일어나는 일은 예측하거나 통제 할 수없는 몇 가지 요인에 달려 있습니다. 때로는 불만없이 성공적으로 읽고 쓰는 것 같습니다. 다른 때에는 끔찍하고 효과적으로 프로그램을 중단시킬 수 있습니다.

중요한 것은 절대 정의되지 않은 동작을 사용하거나 의존해서는 안됩니다. 불행하게도 한 번의 테스트가 성공했기 때문에 항상 성공할 것이라고 생각하는 일반적인 루키 실수입니다. 그것은 분명히 사실이 아니며, 조만간 재앙을위한 처방입니다.