2009-04-07 2 views
3

나는 다음과 같은 선언 헤더를 주어졌다 :이 선언은 어떻게 변경해야합니까?

//The index of 1 is used to make sure this is an array. 
MyObject objs[1]; 

그러나, 나는이 배열은 동적으로 프로그램이 시작되어 하나의 크기 확인해야합니다. 나는 이것을 MyObject * objs로 선언해야한다고 생각 하겠지만 원래 프로그래머가 이런 식으로 선언했다면 어떤 이유가있을 것입니다.

어쨌든 동적으로 크기를 조정할 수 있습니까? 아니면 포인터로 변경 한 다음 malloc()로 변경해야합니까?

어떻게 든 새 키워드를 사용해도 되겠습니까?

답변

6

정확합니다. 크기를 동적으로 인스턴스화하려면 포인터를 사용해야합니다.

MyObject* objs = new MyObject[size]; 
+0

해야합니다, MyObject * objs = new MyObject [size]; 권리? – Tjofras

+0

아, 네 말이 맞는 것 같아. 나는 C#에 감염되어서 내 C++을 오염시켰다. :) –

16

사용 STL vector는 :

#include <vector> 

std::vector<MyObject> objs(size); 

벡터는 dynamic array하고 Standard Template Library의 일부입니다. 배열로 객체가 push back이되면 자동으로 크기가 조정되고 [] operator으로 일반 C 배열처럼 액세스 할 수 있습니다. 또한 &objs[0]은 컨테이너가 비어 있지 않은 경우 list과 달리 메모리의 인접한 시퀀스를 가리킬 수 있습니다.

+0

"& objs [0]은 연속적인 연속열을 가리키는 것이 보장됩니다."하지만, 벡터가 비어 있지 않은 경우 (예 : empty() 메소드 사용)에만 확인하십시오. 그렇지 않으면 정의되지 않은 동작이 발생할 수 있습니다. –

+0

그건 사실이고 지적했습니다. –

+0

미리 크기를 알고 있으면 Vector :: reserve()가 도움이됩니다. –

0

동적 크기 조정 배열을 원한다면 STL을 사용하는 것이 가장 좋은 방법이며, 하나는 std::vector입니다. 삽입에 신경 쓰지 않는다면 std :: list를 사용할 수도 있습니다.

+0

그래도 문제는 해결되지 않습니다. 포인터를 포인터로 변경할 수 있다면 크기를 조정할 수있는 옵션이 많습니다. realloc은 현재 선언을 사용하는 동안 배열의 크기를 조정할 수 없습니다. – jalf

0

그것 보인다 (당신이 왜 대신 의 malloc새로운 연산자를 사용하지 ++ C를 사용하고 있기 때문에?) - 그래, 당신이 변경을 할 수 있습니다.
하지만 sizeof (objs)에서 코드를 확인하십시오.

MyObj *arr1 = new MyObj[1]; 
MyObj arr2[1]; 

sizeof(arr1) != sizeof(arr2) 

아마도이 사실은 코드의 어딘가에서 사용되었을 것입니다.

3

아니면 단지 포인터로 변경 한 다음 malloc()으로 변경해야합니까?

이렇게하면 malloc 된 메모리에있는 객체에 대해 생성자가 어떻게 호출 될 것입니까? 나는 당신에게 힌트를 줄 것이다 - 그들은되지 않을 것이다 - 당신은 std :: vector를 사용할 필요가있다.

0

그 의견은 크게 나쁩니다. 한 요소 배열은 주석이 다르게 제안하더라도 배열입니다.

나는 누구도 이런 식으로 "배열"을 시행하는 것을 본 적이 없습니다. 배열 구문은 주로 구문 설탕 (a[2]2[a]과 동일한 결과를 제공합니다. 즉, 이유가 없어도 프로그래머를 혼란스럽게 할 것이므로 a (참고this is an interesting and valid syntax but usually a very bad form to use)의 세 번째 요소).

배열 구문은 대부분 구문 론적 설탕이므로 포인터로 전환하는 것이 좋습니다.그러나 만약 당신이 그것을 할 예정이라면, new[]으로가는 것이 더 의미가 있습니다. (생성자를 무료로 불러 오기 때문에) std::vector으로가는 것이 훨씬 더 합리적입니다. (모든 장소에서 delete[]에 전화하는 것을 기억할 필요가 없기 때문입니다.) 배열은 반환, 중단, 명령문의 끝, 예외 발생 등으로 인해 범위를 벗어납니다.

1

구조체 또는 공용 구조체 내부의 포인터로 사용 된 배열 만 보았습니다. 이것은 오래 전이었고 스크립트 언어에 대한 문자열 비교 속도를 향상시키기 위해 문자열의 len 및 첫 번째 문자를 해시로 처리하는 데 사용되었습니다.

코드는 다음과 유사했다 :

union small_string { 
    struct { 
     char len; 
     char buff[1]; 
    }; 
    short hash; 
}; 

다음의 malloc을 사용하여 초기화 된 small_string의 C 캐스트 효과적으로 reinterpret_cast

small_string str = (small_string) malloc(len + 1); 
strcpy(str.buff, val); 

입니다주의와 평등에 대한 테스트

int fast_str_equal(small_string str1, small_string str2) 
{ 
    if (str1.hash == str2.hash) 
     return strcmp(str1.buff, str2.buff) == 0; 
    return 0; 
} 

알다시피 이식성이 좋고 안전한 스타일의 C++는 아닙니다. 그러나 대부분의 스크립팅 언어의 기초가되는 짧은 문자열로 색인 된 연관 배열의 속도가 크게 개선되었습니다.

나는 아마이 스타일의 C++를 피할 것이다.

1

구조체의 끝 부분에 있나요? 내가 본

한 트릭은 그래서 arr 변수 크기의 배열이된다 sizeof (struct foo)보다 구조체

struct foo { 
/* optional stuff here */ 
int arr[1]; 
} 

및 malloc에 ​​더 많은 메모리를 선언하는 것입니다.

이것은 가변 크기의 배열을 사용할 수 없어서 C 프로그램을 해킹했을 때 상당히 일반적으로 사용되었습니다. 추가 할당을 수행하는 것은 오류가 발생하기 쉬운 것으로 간주되었습니다.

할 일은 거의 모든 경우에 배열을 STL 벡터로 변경하는 것입니다.

관련 문제