new
연산자(C++)
지정하거나 자리 표시자 형식의 개체 또는 개체 배열을 할당하고 초기화하려고 시도하고 개체(또는 배열의 초기 개체)에 적합한 형식의 0이 아닌 포인터를 반환합니다.
구문
new-expression
:
::
optnew
new-placement
optnew-type-id
new-initializer
opt
::
optnew
new-placement
opt(
type-id
)
new-initializer
opt
new-placement
:
(
expression-list
)
new-type-id
:
type-specifier-seq
new-declarator
opt
new-declarator
:
ptr-operator
new-declarator
opt
noptr-new-declarator
noptr-new-declarator
:
[
expression
]
attribute-specifier-seq
opt
noptr-new-declarator
[
constant-expression
]
attribute-specifier-seq
opt
new-initializer
:
(
expression-list
opt)
braced-init-list
설명
실패 new
하면 0을 반환하거나 예외를 throw합니다. 자세한 내용은 The new
and delete
Operators를 참조하세요. 사용자 지정 예외 처리 루틴을 작성하고 함수 이름을 인수로 사용하여 런타임 라이브러리 함수를 호출 _set_new_handler
하여 이 기본 동작을 변경할 수 있습니다.
C++/CLI 및 C++/CX에서 관리되는 힙에 개체를 만드는 방법에 대한 자세한 내용은 gcnew를 참조하세요.
참고 항목
Microsoft C++ 구성 요소 확장(C++/CX)은 vtable 슬롯 항목을 추가하는 키워드(keyword) 지원 new
합니다. 자세한 내용은 (vtable의 새 슬롯)을 참조 new
하세요.
C++ 클래스 개체에 대한 메모리를 할당하는 데 사용되는 경우 new
메모리가 할당된 후 개체의 생성자가 호출됩니다.
연산자를 delete
사용하여 연산자가 할당한 메모리의 할당을 취소합니다 new
. 연산자를 delete[]
사용하여 연산자가 할당한 배열을 삭제합니다 new
.
다음 예제에서는 크기가 dim
의 10배인 2차원 문자 배열을 할당한 다음 해제합니다. 다차원 배열을 할당할 때 첫 번째를 제외한 모든 차원은 양수 값으로 계산되는 상수 식이어야 합니다. 가장 왼쪽 배열 차원은 양수 값으로 계산되는 식일 수 있습니다. 연산자를 사용하여 new
배열을 할당하는 경우 첫 번째 차원은 0일 수 있으며 연산자는 new
고유한 포인터를 반환합니다.
char (*pchar)[10] = new char[dim][10];
delete [] pchar;
, type-id
클래스 선언 또는 열거형 선언을 포함const
volatile
할 수 없습니다. 다음 식의 형식이 잘못되었습니다.
volatile char *vch = new volatile char[20];
연산자는 new
개체가 아니므로 참조 형식을 할당하지 않습니다.
연산자는 new
함수를 할당하는 데 사용할 수 없지만 함수에 포인터를 할당하는 데 사용할 수 있습니다. 다음 예제에서는 정수를 반환하는 함수에 대한 7개의 포인터 배열을 할당한 다음 해제합니다.
int (**p) () = new (int (*[7]) ());
delete p;
추가 인수 없이 연산 new
자를 사용하고 , /EHa
또는 /EHs
옵션으로 /GX
컴파일하는 경우 생성자가 예외를 throw하는 경우 컴파일러는 연산 delete
자를 호출하는 코드를 생성합니다.
다음 목록에서는 다음의 new
문법 요소를 설명합니다.
new-placement
오버로드 new
하는 경우 추가 인수를 전달하는 방법을 제공합니다.
type-id
할당할 형식을 지정합니다. 기본 제공 또는 사용자 정의 형식일 수 있습니다. 형식 사양이 복잡한 경우 괄호로 묶어 바인딩 순서를 강제로 지정할 수 있습니다. 형식은 컴파일러에 의해 형식이 결정되는 자리 표시자(auto
)일 수 있습니다.
new-initializer
초기화된 개체의 값을 제공합니다. 배열에 대해 이니셜라이저를 지정할 수 없습니다. 연산자는 new
클래스에 기본 생성자가 있는 경우에만 개체 배열을 만듭니다.
noptr-new-declarator
배열의 범위를 지정합니다. 다차원 배열을 할당할 때 첫 번째를 제외한 모든 차원은 변환 가능한 std::size_t
양수 값으로 계산되는 상수 식이어야 합니다. 가장 왼쪽 배열 차원은 양수 값으로 계산되는 식일 수 있습니다. 연결된 attribute-specifier-seq
배열 형식에 적용됩니다.
예: 문자 배열 할당 및 해제
다음 코드 예제는 문자 배열 및 CName
클래스 개체를 할당한 다음 해제합니다.
// expre_new_Operator.cpp
// compile with: /EHsc
#include <string.h>
class CName {
public:
enum {
sizeOfBuffer = 256
};
char m_szFirst[sizeOfBuffer];
char m_szLast[sizeOfBuffer];
public:
void SetName(char* pszFirst, char* pszLast) {
strcpy_s(m_szFirst, sizeOfBuffer, pszFirst);
strcpy_s(m_szLast, sizeOfBuffer, pszLast);
}
};
int main() {
// Allocate memory for the array
char* pCharArray = new char[CName::sizeOfBuffer];
strcpy_s(pCharArray, CName::sizeOfBuffer, "Array of characters");
// Deallocate memory for the array
delete [] pCharArray;
pCharArray = NULL;
// Allocate memory for the object
CName* pName = new CName;
pName->SetName("Firstname", "Lastname");
// Deallocate memory for the object
delete pName;
pName = NULL;
}
예: new
연산자
연산자의 배치 형식 new
(크기보다 인수가 많은 폼)을 사용하는 경우 생성자가 예외를 throw하는 경우 컴파일러는 연산자의 배치 형식 delete
을 지원하지 않습니다. 예시:
// expre_new_Operator2.cpp
// C2660 expected
class A {
public:
A(int) { throw "Fail!"; }
};
void F(void) {
try {
// heap memory pointed to by pa1 will be deallocated
// by calling ::operator delete(void*).
A* pa1 = new A(10);
} catch (...) {
}
try {
// This will call ::operator new(size_t, char*, int).
// When A::A(int) does a throw, we should call
// ::operator delete(void*, char*, int) to deallocate
// the memory pointed to by pa2. Since
// ::operator delete(void*, char*, int) has not been implemented,
// memory will be leaked when the deallocation can't occur.
A* pa2 = new(__FILE__, __LINE__) A(20);
} catch (...) {
}
}
int main() {
A a;
}
할당된 개체 초기화 new
선택적 new-initializer
필드는 연산자의 문법에 포함됩니다 new
. 이 필드를 사용하면 사용자 정의 생성자를 사용하여 새 개체를 초기화할 수 있습니다. 초기화가 수행되는 방법에 대한 자세한 내용은 이니셜라이저를 참조 하세요. 다음 예제에서는 연산자를 사용하여 초기화 식을 new
사용하는 방법을 보여 줍니다.
// expre_Initializing_Objects_Allocated_with_new.cpp
class Acct
{
public:
// Define default constructor and a constructor that accepts
// an initial balance.
Acct() { balance = 0.0; }
Acct( double init_balance ) { balance = init_balance; }
private:
double balance;
};
int main()
{
Acct *CheckingAcct = new Acct;
Acct *SavingsAcct = new Acct ( 34.98 );
double *HowMuch = new double { 43.0 };
// ...
}
이 예제에서는 연산자를 사용하여 개체 CheckingAcct
가 new
할당되지만 기본 초기화는 지정되지 않았습니다. 따라서 클래스 Acct()
의 기본 생성자가 호출됩니다. 그런 다음 개체 SavingsAcct
는 명시적으로 34.98로 초기화된다는 점을 제외하고 동일한 방식으로 할당됩니다. 34.98은 형식이므로 해당 형식 double
의 인수를 사용하는 생성자가 초기화를 처리하기 위해 호출됩니다. 마지막으로 클래스가 아닌 형식 HowMuch
은 43.0으로 초기화됩니다.
개체가 클래스 형식이고 해당 클래스에 생성자가 있는 경우(이전 예제와 같이) 다음 조건 중 하나가 충족되는 경우에만 연산자가 개체를 초기화 new
할 수 있습니다.
이니셜라이저에 제공된 인수는 생성자의 인수와 일치합니다.
클래스에 기본 생성자(인수 없이 호출할 수 있는 생성자)가 있습니다.
연산자를 사용하여 new
배열을 할당할 때는 요소별 명시적 초기화를 수행할 수 없습니다. 기본 생성자(있는 경우)만 호출됩니다. 자세한 내용은 기본 인수를 참조 하세요.
메모리 할당이 실패하면(operator new
값 0을 반환) 초기화가 수행되지 않습니다. 이 동작은 존재하지 않는 데이터를 초기화하려는 시도로부터 보호합니다.
함수 호출과 마찬가지로 초기화된 식이 계산되는 순서는 정의되지 않습니다. 또한 메모리 할당이 발생하기 전에 이러한 식을 완전히 평가해서는 안 됩니다. 메모리 할당이 실패하고 연산자가 new
0을 반환하면 이니셜라이저의 일부 식이 완전히 계산되지 않을 수 있습니다.
할당된 개체의 수명 new
연산자를 new
사용하여 할당된 개체는 정의된 범위가 종료될 때 제거되지 않습니다. 연산자는 new
할당하는 개체에 대한 포인터를 반환하므로 프로그램에서 해당 개체에 액세스하고 삭제하기 위해 적절한 범위의 포인터를 정의해야 합니다. 예시:
// expre_Lifetime_of_Objects_Allocated_with_new.cpp
// C2541 expected
int main()
{
// Use new operator to allocate an array of 20 characters.
char *AnArray = new char[20];
for( int i = 0; i < 20; ++i )
{
// On the first iteration of the loop, allocate
// another array of 20 characters.
if( i == 0 )
{
char *AnotherArray = new char[20];
}
}
delete [] AnotherArray; // Error: pointer out of scope.
delete [] AnArray; // OK: pointer still in scope.
}
AnotherArray
포인터가 예제 범위를 벗어나면 개체를 더 이상 삭제할 수 없습니다.
new
작동 방법
연산자를 new
포함하는 식은 new-expression
다음 세 가지 작업을 수행합니다.
할당할 개체에 대한 스토리지를 찾고 예약합니다. 이 단계가 완료되면 올바른 양의 스토리지가 할당되지만 아직 개체는 아닙니다.
개체를 초기화합니다. 초기화가 완료되면 할당된 스토리지가 개체가 되는 데 충분한 정보가 있습니다.
파생되거나
type-id
파생된new-type-id
포인터 형식의 개체에 대한 포인터를 반환합니다. 프로그램에서는 이 포인터를 사용하여 새로 할당된 개체에 액세스합니다.
new
연산자는 함수operator new
를 호출합니다. 모든 형식의 배열 및 전역 함수::operator new
가 아닌 class
struct
개체의 union
경우 스토리지를 할당하기 위해 호출됩니다. 클래스 형식 개체는 클래스별로 자체 operator new
정적 멤버 함수를 정의할 수 있습니다.
컴파일러가 형식T
의 개체를 할당하는 연산자를 발견 new
하면 호출을 T::operator new( sizeof(T) )
실행하거나 사용자 정의 operator new
가 정의::operator new( sizeof(T) )
되지 않은 경우 호출을 실행합니다. 연산자가 개체에 new
대해 올바른 양의 메모리를 할당할 수 있는 방법입니다.
참고 항목
인수 operator new
는 형식 std::size_t
입니다. 이 형식은 direct.h>, malloc.h>, <memory.h, <search.h>>, <stddef.h, <stdio.h>, <<stdlib.h>>, <string.h> 및 <time.h>에 정의<됩니다.
문법의 옵션을 사용하면 (연산자에 대한new
문법 참조) 사양 new-placement
을 사용할 수 있습니다. 매개 변수는 new-placement
사용자 정의 구현에만 사용할 수 있습니다. operator new
이 매개 변수는 추가 정보를 전달할 operator new
수 있습니다. 필드가 있는 new-placement
식은 클래스 T에 T *TObject = T::operator new( sizeof( T ), 0x0040 );
멤버operator new
가 있는 경우로 변환되고, 그렇지 않으면 T *TObject = ::operator new( sizeof( T ), 0x0040 );
로 변환 T *TObject = new ( 0x0040 ) T;
됩니다.
필드의 new-placement
원래 의도는 사용자가 지정한 주소에서 하드웨어 종속 개체를 할당할 수 있도록 하는 것이었습니다.
참고 항목
앞의 예제에서는 필드에 하나의 인수만 표시하지만 이러한 방식으로 전달할 operator new
수 있는 new-placement
추가 인수 수에는 제한이 없습니다.
클래스 형식T
에 대해 정의된 경우에도 operator new
다음 예제와 같이 전역 연산 new
자를 명시적으로 사용할 수 있습니다.
T *TObject = ::new TObject;
범위 확인 연산자(::
)는 전역 new
연산자를 강제로 사용합니다.
참고 항목
피드백
https://aka.ms/ContentUserFeedback
출시 예정: 2024년 내내 콘텐츠에 대한 피드백 메커니즘으로 GitHub 문제를 단계적으로 폐지하고 이를 새로운 피드백 시스템으로 바꿀 예정입니다. 자세한 내용은 다음을 참조하세요.다음에 대한 사용자 의견 제출 및 보기