2016-12-06 2 views
1

나는이 주제 (배열)에서 내 의견으로는 명확하지 않은 C++ 읽기 Stroustrup의 책을 연구 중이다. 에서 내가 이해 한 내용을 C++이 배열의 두 종류 (델파이와 같은) :라고 벡터동적 및 정적 배열

std::vector<int> a; 

a.push_back(10); 
a.push_back(487); 
a.push_back(-22); 

int test[3] = {10,487,-22}; 

동적 배열처럼 선언

정적 배열 나는 이미 이것에 대한 해답을 보았지만 (내부에 수많은 선과 개념이 있었다) 개념을 분명히하지 않았다. 내가 vector의 이해 무슨에서


더 많은 메모리를 소비하지만 그들은 (사실, 동적으로) 자신의 크기를 변경할 수 있습니다. 배열은 대신 컴파일 타임에 주어진 고정 크기를가집니다.

Stroustrup 장에서 이유는 설명하지 않고 배열이없는 동안 벡터가 안전하다고 설명했습니다. 나는 그를 정말로 신뢰하지만, 왜 그럴까요? 이유 안전은 기억의 위치와 관련이 있습니까? (힙/스택)

안전하다고 생각하면 왜 벡터를 사용하고 있는지 알고 싶습니다.

+0

std :: vector, 배열 및 포인터를 사용하여 장점 및 함정에 대해 질문하는 경우 매우 광범위한 토론입니다. –

+0

내 코드에서는 이전 버전에서 사용 된 사람을 찾은 경우에만 항상 벡터와 배열을 사용하려고합니다. 하지만 왜 –

+0

std :: vector가 이전에 배열로 해결 된 대부분의 작업을 수행 한 잘 연마 된 기계인지 알고 싶습니다. std :: vector의 설계 방법과 이유를 연구하고 싶습니다. 여기에는 알고리즘 작동뿐만 아니라 자원 관리 (3/5 규칙)가 포함됩니다. –

답변

3

배열이 안전하지 않은 이유는 메모리 누수 때문입니다.

동적 배열을

int * arr = new int[size] 

를 선언하고, [] 도착 후 메모리가 해제되지 않은 남아 있고 이것은 메모리 누출이라고 삭제하지 않으면. C++에서 new라는 단어를 사용할 때마다 메모리를 확보하기 위해 어딘가에 삭제가 있어야합니다. malloc()을 사용한다면, free()가 사용되어야한다.

http://ptolemy.eecs.berkeley.edu/ptolemyclassic/almagest/docs/prog/html/ptlang.doc7.html

또한 크기 -1보다 큰 인덱스 값을 삽입하는 예를 들어, 어레이의 경계 밖으로 이동하기가 매우 쉽다. 벡터를 사용하면 원하는만큼 많은 요소를 push_back() 할 수 있으며 벡터의 크기가 자동으로 조정됩니다. 크기가 15 인 배열을 가지고 arr [18] = x라고 말하면, 세그먼트 화 오류가 발생합니다. 프로그램은 컴파일되지만 어레이 경계 밖으로 출력하는 명령문에 도달하면 충돌합니다.

일반적으로 코드가 큰 경우 배열이 자주 사용되지 않습니다. 벡터는 객관적으로 거의 모든면에서 월등하므로 배열을 사용하면 무의미 해집니다.

편집 : 폴 맥켄지는 세그먼트 오류를 ​​보장하지 않습니다 배열 범위의 외출, 코멘트에 지적 아니라 정의되지 않은 동작이 어떻게되는지 확인하기 위해 컴파일러까지이므로

+0

그들은 더 많은 공간을 필요로합니다. 그러나 전반적으로 나는 벡터를 선호해야합니다. 나는 "안전"이 어디에 있는지 이해했다고 생각한다 :) 벡터는 많은 유용한 방법으로 구현 될 수있다. 배열은 "고대"이며 C 레트로 호환성을 위해 사용될 수 있습니다 –

+0

이것은 사실입니다. 벡터는 더 많은 저장 공간을 사용하지만 벡터와 함께 제공되는 보안/효율성 이점에 비해 성이 불투명합니다 –

+2

@ConnorSchwinghammer - * 크기가 15이고 arr [18] = x라고 말하면 세그먼트 화 오류 * - 벡터에 대해'[]'를 사용하여 범위를 벗어나는 경우 세그멘테이션 오류가 보장되지 않습니다 (예, 디버그 Visual C++ 런타임은 확인하지만 릴리스 버전은 확인하지 않음).그래서 당신은 기본적으로 아웃 오브 바운드 (out of bound)를 할 때 일반 배열을 사용할 때와 같은 정의되지 않은 동작을 겪을 수 있습니다. 그러나'vector'는'at()'함수를 가지고 있습니다.이 함수는 인덱스가 범위를 벗어나면'std :: out_of_range' 예외가 발생한다는 것을 보장합니다. 그럼 답을 수정해야할까요? – PaulMcKenzie

-4

하나의 보안은 거기에없는 벡터에서 무언가를 액세스 할 수 없다는 것을 알 수 있습니다.

나는 그것이 의미하는 바는, push_back 요소가 4 개 뿐이므로 색인 7에 액세스하려고 시도하면 오류가 다시 발생합니다. 그러나 배열에서는 일어나지 않습니다.

즉, 손상된 데이터에 액세스하는 것을 중지합니다.

편집 :

프로그래머는 오류가 발생하는 vector.size()와 인덱스를 비교해야한다. 자동으로 자동 실행되지 않습니다. 하나는 혼자서해야합니다.

+0

이것은 대부분의 경우 사실이 아닙니다. –

+0

@CaptainGiraffe, 인덱스 번호를 사용하기 전에 vector.size()와 비교해 볼 수 있으며 바운드인지 여부를 결정할 수 있습니다. –

+0

배열을 합리적으로 사용하는 경우에도 마찬가지입니다. –

2

우리가 보자 파일에서 숫자를 읽는 경우.
파일에 몇 개의 숫자가 들어 있는지 알 수 없습니다.

숫자를 저장할 배열을 선언하려면 용량 또는 수량을 알아야합니다. 알 수는 없습니다. 파일 번호가 64 이상이면 파일을 덮어 쓰기 시작합니다. 파일의 크기가 64보다 작 으면 (예 : 16) 메모리를 낭비합니다 (48 슬롯을 사용하지 않음). 우리가 필요로하는 것은 컨테이너 (배열)의 크기를 동적으로 조정하는 것입니다.

어레이의 용량을 동적으로 조정하려면 더 큰 더 큰 어레이를 작성한 다음 요소를 복사하고 이전 어레이를 삭제해야합니다.

std::vector은 필요에 따라 용량을 조정합니다. 그것은 당신을위한 메모리의 동적 할당을 처리합니다.

또 다른 측면은 컨테이너를 함수로 전달하는 것입니다. 배열을 사용하려면 배열과 용량을 전달해야합니다. std::vector을 사용하면 벡터 만 전달하면됩니다. 벡터 객체는 그 용량에 대해 질의를받을 수 있습니다.