0

나는 구조체가있는 클래스 (또는 외부, 그것이 중요하지 않길 바래) 안에 한 클래스가있는 프로그램을 작성하고 있습니다. 그 클래스에서 구조체 요소의 배열을 만들 필요가 있습니다. (예를 들어 벡터를 사용할 수 있지만 프로그램에서는 간단한 동적 배열 만 사용할 수 있습니다.)구조체 요소의 배열 크기를 조정하는 방법

배열을 T * arr[SIZE]으로 선언합니다. 여기서 T은 내 구조체입니다. 유일한 문제는 배열의 정확한 크기를 알지 못하고 필요한 경우 크기를 늘릴 필요가 있다는 것입니다. 그래서 크기를 조정하는 기능 썼다 :

if(some cond){ 
    T * tmpArr[newSIZE]; 
    memcpy(tmp, db, newSIZE*sizeof(T)); 
    delete [] arr; 
    arr = tmpArr; 
} 

을하지만 MyClass::T[....] 내가 추측 내 arr = tmpArr 표현에 응답 MyClass::T*[SIZE]와 호환되지 않는 오류를 받고 있어요.

내가 잘못하고있는 것을 말해 줄 수 있습니까? 그리고 T * arr[size] 또는 T * arr = new T[size]을 선언하는 것이 더 좋고,이 경우 어떻게 배열의 크기를 조정하고 (이전의 메모리를 늘릴 수 있습니까?) 어떻게해야합니까?

UPDATE : 답변

감사합니다, 나는 내 프로그램에 따라 한 :

T * tmp = new T[newSIZE]; 
    memcpy(tmp, db, newSIZE*sizeof(T)); 
    delete [] db; 
    db = tmp; 

을 그리고 지금은 tmp에 DB를 삭제하고 db를 할당 한 후, 이상한 일을지고있어 내가 모든 인쇄하려고 db (또는 tmp)에 포함 된 데이터, 그 이상한 것 :

Smith2 Michigan ave▒ ACME, Ltd. One ACME roa▒ 
    Smit▒ Michigan ave` ACME, Ltd. One ACME roa " 

    One ACME road#@"▒▒▒▒Michigan ave`▒▒▒▒Smit▒" 

    ▒▒ ▒8 Ltd.#Michigan avenuemith4▒aF▒ 

삭제하고 지정하기 전에 동일한 데이터를 인쇄하면 내가 원하는 일반 텍스트. 그리고 프로그램을 마친 후에 (이전에 없었던 코드로 인해 문제가 발생했을 수 있으므로 Segmentation 오류가 발생합니다). 그건 그렇고, 난 structstd::string와 내 창문에 cygwin을 사용하고 있습니다. 여기에 무슨 문제가 있는지 생각해?

T array[size]; 

그러나이에 삭제 호출해서는 안 :

+2

'tmpArr'은 포인터의 배열입니다. 그건 원치 않는 것 같습니다. 그러나 다시 전체 코드는 약간 의미가 없습니다. –

+0

* "유일한 문제는 배열의 정확한 크기를 알 수 없다는 것입니다."* 크기를 직접 추적해야합니다. –

+0

'std :: vector'를 사용하십시오. –

답변

1

나는 당신이 다음과 같이 생성 된 배열을 삭제하려고하는 것 같아요. 이 배열은 범위를 벗어나면 삭제됩니다. 배열을 생성하고 나중에 자유롭게 배열하려면 배열을 선언 할 때 new 연산자를 사용해야합니다. 그것을 무료로 하시려면 delete을 사용하십시오.

하지만 어쨌든 직접 시도하는 대신 std::vector을 사용하는 것이 좋습니다. 이 자료에 대해 배우고 싶다면 Stephen T. Lavavej가 작성한 Microsoft의 channel9에있는 비디오 시리즈가 있습니다 :

http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Standard-Template-Library-STL-/C9-Lectures-Introduction-to-STL-with-Stephan-T-Lavavej 진짜 보석입니다.

3
T arr[N]; 

이러한 형태의 선언하면 자동 저장 기간이 N 크기의 어레이를 제공한다. 이 문제가 해결되었습니다. 이 배열의 크기는 변경할 수 없습니다. 크기 N은 컴파일 타임 상수 여야합니다.

T* arr = new T[N]; 

이 선언은 자동 저장 기간이 T*입니다. 그러나 동적 저장 기간이 인 크기 배열 N도 생성합니다.여기에서 크기 N은 컴파일 타임 상수 일 필요는 없습니다.

그러나 이것은 도움이되지 않습니다. 크기 조정 동적 배열을 여전히 사용할 수 없습니다. 이전 배열을 삭제하려면 delete[] arr을 수행 한 다음 new T[NewSize]을 수행하고 어떻게 든 데이터를 복사해야합니다.

이것은 지저분 해지기 쉽고, 실제로 가지고 있습니다. 코드에서 두 가지 유형의 할당을 혼합합니다. arr에 동적 저장 기간이 없더라도 delete[] arr을 (를) 시도하고 있습니다. 당신은 단순히 이것을 할 수 없습니다. arr = tmpArr;과 같이 배열 하나를 다른 배열에 할당 할 수도 없습니다.

대신 C++ 표준 라이브러리는 컨테이너라고하는 여러 가지 유형을 제공합니다. 이것들은 동적으로 사이즈를 재조정 할 수있는 요소들의 시퀀스를 가지는 것을 매우 쉽게 만듭니다. 예를 들어, std::vector<T>을 사용하는 것이 훨씬 나을 것입니다.

std::vector<T> arr; 

std::vector은 요소없이 시작됩니다. arr.push_back(value)을 수행하여 요소를 간단히 추가 할 수 있습니다. arr.resize(newSize)을 실행하여 벡터 크기를 아주 쉽게 조절할 수 있습니다.

+0

답해 주셔서 고맙습니다.하지만 오류없이 동적 배열을 크기 조정하거나 삭제/복사 할 수있는 방법을 말씀해 주시겠습니까? – NGix

0

단순한 솔루션은 사각 휠을 재발 명하는 것이 아니라 표준 원형 라이브러리에서 이미 둥글고 세련된 std::vector<Type> 템플릿을 사용하는 것입니다.

4

T* tmpArr[newSIZE];는 가변 길이를 포인터 T-의 배열을 선언한다. 가변 길이 배열은 표준 C++의 일부가 아닙니다 (C99의 일부이지만 C++에서는 GCC의 확장으로만 사용 가능합니다 ... 따라서이 코드는 다른 컴파일러와 호환되지 않습니다).

완벽하게 합리적인 해결책은 std::vector을 사용하는 것이지만, 직접 사용할 수 없다고 썼다면 다음은 할 수있는 일입니다. 기존의 배열이 delete[]를 사용 memcpy(newArr, arr, size * sizeof(T))

  • 가 할당 해제 : 기존 배열에서 T* newArr = new T[newSize]
  • 복사 요소 :
    1. 새로운 배열을 할당 :

      1. 변화 T* tmpArr[newSIZE]; 지금
      2. 이 배열의 크기를 조정하는 T* arr = new T[size];-delete[] arr
      3. delete는 포인터 자체를 변경하지 않기 때문에 h 3 단계 이후에 유효하지 않은 ( 매달려) 포인터를 AVE, 그래서 이전에 새로운 배열의 첫 번째 요소에 대한 포인터를 할당합니다 arr = newArr
    2. 이 배열의 크기를 추적 당신이
    로 작업

    T* arr = new T[size]은 유형의 size 개체를 저장할 수있는 메모리를 할당하고 기본 생성자 T을 사용하여 이러한 개체를 구성합니다. 첫 번째 요소의 주소는 arr에 할당되어 연속적인 메모리 블록을 가리키며,이 요소들은 상주합니다.

  • +1

    'memcpy'는'C++ '에서'T'가 작동하지 않는 것 같습니다. 다른 객체 멤버를 가진 클래스 (예 : std :: string). 새 배열을 할당 한 후에는 이전 배열을 반복하고 새 배열에서 하나씩 항목을 할당해야합니다. 그러면 최소한 기본 복사 생성자가 호출됩니다. 'memcpy'는 struct와 함께'C'에 포팅 된 것과 똑같은 resize 함수에서 예상대로 작동하고'std :: string' 대신'char [n]'또는'char * + malloc (n * sizeof (char))'. – A4L

    0

    실제로 포인터를 T에 저장하려고한다고 가정합니다. 당신이 T 포인터의 배열을 할당하고 있기 때문에

  • 그래서 tmpArrarr
  • 의 크기를 제거, 누락 *를 추가

    • :

      // arr definition 
      T **arr;; 
      
      // arr resizing code 
      if(some cond){ 
          T **tmpArr; 
          memcpy(tmp, db, newSIZE*sizeof(T *)); 
          delete [] arr; 
          arr = tmpArr; 
      } 
      
      당신이 필요

      귀하의 배열 에 포인터를 T, 아니 TtmpArr 크기를 컴파일 할 때 알 수 없으므로 해당 형식에서 지정할 수 없습니다.

      경고 : 새로운 크기가 현재 크기보다 작 으면 배열 끝에 포인터가 없어집니다. 그 코드에 배열의 크기를 늘려야하기 때문에이 코드에 대한 테스트를 추가하고이 여분의 T (컨테이너가 코드를 소유하고있는 경우)을 삭제하거나 단순히 예외를 throw해야합니다.

    관련 문제