C ++의 정적 배열과 동적 배열


93

C ++에서 정적 배열과 동적 배열의 차이점은 무엇입니까?

내 수업에 할당을해야하는데 정적 배열을 사용하지 말고 동적 배열 만 사용하라는 메시지가 표시됩니다. 책과 온라인을 봤지만 이해가 안되는 것 같습니다.

나는 정적이 컴파일 타임에 생성되고 런타임에 동적이라고 생각했지만 이것을 메모리 할당으로 착각 할 수 있습니다.

C ++에서 정적 배열과 동적 배열의 차이점을 설명 할 수 있습니까?


1
정적은 동적의 반대가 아닙니다. 사용중인 책이 끔찍하거나 문맥에서 벗어난 것입니다. 이 문제를 해결하기 위해 아래에 새 답변을 추가하겠습니다.
Joshua Clayton

3
이 질문의 다이어그램을 참조하십시오. stackoverflow.com/a/11698458/1143274 정적 배열은 스택 또는 힙에 할당되지 않습니다.
Evgeni Sergeev

* 고정 어레이 대 동적 어레이
csguy

답변:


105

로컬 어레이는 스택에 생성되고 자동 저장 기간이 있습니다. 메모리를 수동으로 관리 할 필요는 없지만 기능이 종료되면 파괴됩니다. 크기는 반드시 고정되어 있어야합니다.

int foo[10];

로 생성 된 어레이 operator new[]는 동적 저장 기간을 가지며 힙 (기술적으로 "무료 저장소")에 저장됩니다. 크기는 상관 없지만 스택 프레임의 일부가 아니므로 직접 할당하고 해제해야합니다.

int* foo = new int[10];
delete[] foo;

18
이것은 정확하지만 작동 방식을 설명하기위한 것입니다. 실제 코드에서이 작업을 수행하지 말고 대신 std :: vector를 사용하십시오.
Eddy Pronk

23
@Eddy : 그것은 벡터가 필요 여부에 상황에 따라 달라집니다
Casebash

6
@Casebash : 어떤 상황에서 배열을 선호하십니까? "배열 대신 벡터 나 데크를 항상 선호해야합니다." -Herb Sutter (더 뛰어난 C ++)
Eddy Pronk

16
@EddyPronk 메모리 조각화 이유로 고정 배열을 일종의 풀로 사용할 수 있습니다. 모든 경우에 힙이 필요한 것은 아니며 스택 기반 어레이를 사용하면 특별한 이점이 있습니다. std :: vector를 일반적인 안티 패턴 인 황금 망치로 취급하고 있습니다.
void.pointer 2010

4
@EddyPronk : Herb Sutter가 동적 배열을 의미한다고 확신 int* foo = new int[N]합니다.이 배열 은 delete스스로 해야 하므로 예외가있을 때주의해야합니다. 정적 배열에는 이러한 문제가 없습니다.
Alexander Malakhov

33

static은 C 및 C ++의 키워드이므로 일반적인 설명 용어가 아니라 변수 또는 배열에 적용될 때 매우 구체적인 의미가 있습니다. 혼동을 복잡하게 만들기 위해 별도의 컨텍스트 내에서 세 가지 다른 의미를 가지고 있습니다. 이 때문에 정적 배열은 고정 또는 동적 일 수 있습니다.

설명하겠습니다.

첫 번째는 C ++ 전용입니다.

  • 정적 클래스 멤버는 생성자로 인스턴스화되지 않거나 소멸자로 삭제되지 않은 값입니다. 이는 멤버를 초기화하고 다른 방식으로 유지 관리해야 함을 의미합니다. 정적 멤버는 포인터가 null로 초기화 된 다음 생성자가 처음 호출 될 때 할당 될 수 있습니다. (예, 정적 및 동적)

두 가지는 C에서 상속됩니다.

  • 함수 내에서 정적 변수는 함수 호출 사이에 메모리 위치가 보존되는 변수입니다. 한 번만 초기화되고 함수 호출 사이에 값을 유지한다는 점에서 정적입니다 (정적을 사용하면 함수가 재진입되지 않음, 즉 스레드 안전이 아님).

  • 함수 외부에서 선언 된 정적 변수는 동일한 모듈 내에서만 액세스 할 수있는 전역 변수입니다 (다른 #include의 소스 코드 파일).

당신이 묻는 질문 (내 생각에)은 동적 배열과 고정 또는 컴파일 타임 배열의 차이점입니다. 더 쉬운 질문입니다. 컴파일 타임 배열은 미리 결정되며 (프로그램이 컴파일 될 때) 함수 스택 프레임의 일부입니다. 주 기능이 실행되기 전에 할당됩니다. 동적 배열은 런타임에 "new"키워드 (또는 C의 malloc 계열)로 할당되며 크기는 미리 알려지지 않았습니다. 동적 할당은 프로그램 실행이 중지 될 때까지 자동으로 정리되지 않습니다.


4
+1, 귀하의 답변은 가장 정확하고 정확하며 더 많은 표를 받았어야합니다.
Z boson 2014 년

new[]연산자 를 사용하여 배열의 크기를 선언하면 런타임까지 크기를 어떻게 알 수 있습니까? 즉int* p = new int[10]
wulfgarpro

"주 기능이 실행되기 전에 할당됩니다." 관련 블록을 입력하기 전에 스택 변수를 할당하는 이유는 무엇입니까?
AlwaysLearning

스택 변수 (일반적으로 함수의 로컬 변수)는 스택 프레임 내에서 미리 정의 된 크기와 위치를 가지며 주 함수 @AlwaysLearning이 실행되기 전에 전체 스택이 할당됩니다. 함수 호출을 통해 스택 프레임에 들어가면 스택 포인터가 업데이트되지만 새 스택 프레임은 스택 내에 있습니다. 더 이상 스택이 할당되지 않습니다. 사실 너무 큰 변수 (예 : 거대한 배열) 또는 너무 많은 함수 호출이 동시에 열리면이 사이트의 이름이 지정된 스택 오버플로가 발생합니다.
Joshua Clayton

@JoshuaClayton 나는 이것이 정확하지 않다고 생각합니다. 몇 번 입력 될지 모를 때 재귀 함수를 위해 스택 프레임 (복수형에주의)을 어떻게 할당 할 수 있습니까?
AlwaysLearning

11

나는 당신의 수업에서 사용되는 의미가 혼란 스럽다고 생각합니다. '정적'이 의미하는 것은 단순히 '일정한 크기'이고 '동적'이 의미하는 것은 '가변 크기'입니다. 이 경우 일정한 크기의 배열은 다음과 같습니다.

int x[10];

"동적"구조는 런타임에 기본 스토리지를 늘리거나 줄일 수있는 모든 종류의 구조입니다. 대부분의 경우 std::vectorC ++ 표준 라이브러리 의 클래스로 충분합니다. 다음과 같이 사용하십시오.

std::vector<int> x(10); // this starts with 10 elements, but the vector can be resized.

std::vectoroperator[]당신이 배열과 같은 의미로 사용할 수 있도록 정의.


1
"동적 배열"은 동적으로 할당 된 배열 (즉, 런타임에 동적으로 크기를 지정할 수있는 배열)을 의미한다는 것이 상당히 분명하다고 생각합니다. 좋아요new int[10]
jalf 2010-04-20

@jalf : 저는 '정적'이라는 용어에 대해 더 걱정했습니다. 일관성을 위해 "동적 배열"을 할당 또는 가변 크기 배열이라고 부르는 것을 선호합니다.
Ben Collins

정적 배열은 스택에서 자동으로 구현되거나 전역 적으로 데이터 섹션에서 구현 될 수 있기 때문에 좋은 점입니다. 둘 다 정적이지만 내부적으로 액세스하는 코드는 매우 다를 수 있습니다.
Z boson

9

정적 배열에는 컴파일 타임에 메모리가 할당되고 메모리는 스택에 할당됩니다. 반면 동적 배열에는 런타임에 메모리가 할당되고 메모리는 힙에서 할당됩니다.

int arr[] = { 1, 3, 4 }; // static integer array.   
int* arr = new int[3]; // dynamic integer array.

6
전역 배열은 정적 배열이며 스택이 아닌 데이터 섹션에서 구현됩니다.
Z boson

9

용어의 의미를 명확하게 정의하는 것이 중요합니다. 불행히도 정적 및 동적 배열이 의미하는 바에 대한 여러 정의가있는 것 같습니다.

정적 변수정적 메모리 할당을 사용하여 정의 된 변수 입니다. 이것은 C / C ++와 무관 한 일반적인 개념입니다. C / C ++에서는 다음과 같이 전역, 파일 또는 로컬 범위로 정적 변수를 만들 수 있습니다.

int x[10]; //static array with global scope
static int y[10]; //static array with file scope
foo() {
    static int z[10]; //static array with local scope

자동 변수 는 일반적으로 스택 기반 메모리 할당을 사용하여 구현됩니다 . 자동 배열은 다음과 같이 C / C ++로 만들 수 있습니다.

foo() {
    int w[10]; //automatic array

무엇 이러한 배열, x, y, z그리고 w공통점 그들 각각의 크기가 고정되어 컴파일시에 정의되어 있다는 점이다.

자동 배열과 정적 배열의 차이점을 이해하는 것이 중요한 이유 중 하나는 정적 저장소가 일반적으로 개체 파일 의 데이터 섹션 (또는 BSS 섹션 ) 에서 구현되고 컴파일러가 절대 주소를 사용하여 배열에 액세스 할 수 있기 때문입니다. 스택 기반 스토리지로는 불가능합니다.

일반적으로 동적 배열 이 의미 하는 것은 크기를 조정할 수있는 것이 아니라 런타임에 결정된 고정 된 크기로 동적 메모리 할당 을 사용하여 구현 된 배열 입니다 . C ++에서 이것은 new연산자를 사용하여 수행됩니다 .

foo() {
   int *d = new int[n]; //dynamically allocated array with size n     

그러나 다음을 사용하여 런타임에 정의 된 수정 크기로 자동 배열을 만들 수 있습니다 alloca.

foo() {
    int *s = (int*)alloca(n*sizeof(int))

진정한 동적 배열의 경우 std::vectorC ++ (또는 C의 가변 길이 배열 ) 과 같은 것을 사용해야합니다 .

OP의 질문에서 과제는 무엇을 의미 했습니까? 나는 원하는 것이 정적 또는 자동 배열이 아니라 new연산자를 사용하여 동적 메모리 할당을 사용 하거나 예를 사용하여 고정되지 않은 크기의 배열을 사용 하는 것이 분명하다고 생각합니다 std::vector.


3

이 맥락에서 크기가 고정되어 있다는 의미에서 정적이라는 의미라고 생각합니다. std :: vector를 사용하십시오. resize () 함수가 있습니다.


2

런타임시 사용자가 크기를 설정 한 다음 그 후에 고정되는 유사 동적 배열을 가질 수 있습니다.

int size;
cin >> size;
int dynamicArray[size];

표준 C ++의 일부가 아닙니다 (C99 및 gcc 용 컴파일러 확장).
crashmstr

1

정적 어레이 :

  1. 정적 배열에는 컴파일 타임에 메모리가 할당됩니다.
  2. 크기는 고정되어 있습니다.
  3. 스택 메모리 공간에 있습니다.
  4. 예 : : int 배열 [10]; // 크기 10의 배열

동적 배열 :

  1. 메모리는 런타임에 할당됩니다.
  2. 크기는 고정되어 있지 않습니다.
  3. 힙 메모리 공간에 있습니다.
  4. 예 : : int * 배열 = 새로운 int [10];

0

예, 정적 배열은 런타임에 동적 배열이 생성되는 컴파일 타임에 생성됩니다. 메모리 위치와 관련하여 차이가있는 한 정적은 스택에 있고 동적은 힙에 생성됩니다. .net 프레임 워크의 경우와 같이 가비지 수집기가 존재하지 않는 한 힙에있는 모든 것은 메모리 관리가 필요합니다. 그렇지 않으면 메모리 누수 위험이 있습니다.


0

정적 배열 : 효율성. 동적 할당 또는 할당 취소가 필요하지 않습니다.

static modifier를 포함한 함수에서 C, C ++로 선언 된 배열은 정적입니다. 예 : static int foo [5];


1
@admdrew, 그것은 사실이지만 질문에 대한 대답은 잘되지 않았습니다. 가장 좋은 대답은 Joshua Clayton의 대답이지만 더 나은 대답은 이것이 하나라고 생각합니다. stackoverflow.com/questions/17775066/…
Z boson

@Zboson 알아서 반가워요, 감사합니다. 헤와 나는 거의 1 년 전에 내가 그 말을했다는 것을 깨달았다.
admdrew

-3

배열 측면의 요소를 제공하는 정적 arrary meens

배열 측면의 요소를 제공하지 않고 동적 오류가 발생합니다.

예:

     char a[10]; //static array
       char a[];  //dynamic array

그가 옳았다 고 생각합니다. 배열에 대한 정확한 길이는 정적 배열이고 길이를 지정하지 않으면 동적 배열입니다. 그러나 그는 영어를 쓰는 방법을 모르기 때문에 사람들이이 답을 표시하는 이유입니다.
muhammad tayyab
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.