C ++에서 어떻게 'realloc'을 사용합니까?


85

reallocC ++에서 어떻게 할 수 있습니까? 언어에서 누락 된 것 같습니다.newdelete있지만 resize!

내 프로그램이 더 많은 데이터를 읽을 때 버퍼를 재 할당해야하기 때문에 필요합니다. 나는 delete이전 포인터 new를 사용하고 새롭고 더 큰 포인터를 사용 하는 것이 올바른 옵션 이라고 생각하지 않습니다 .


8
스트로브 스트 룹은 오랫동안 다시는 볼이 대답 www2.research.att.com/~bs/bs_faq2.html#renew (즉, 당신은 클라인의 C ++ FAQ와 함께 C ++를 처음 사용하는 경우 좋은 시작입니다.)
dirkgently

8
@dirkgently에 의해 참조 대답은 지금 : stroustrup.com/bs_faq2.html#renew - 그리고 클라인의 질문은 이제 슈퍼 자주 묻는 질문의 일부입니다 isocpp.org/faq
maxschlepzig

답변:


54

:: std :: vector를 사용하십시오!

Type* t = (Type*)malloc(sizeof(Type)*n) 
memset(t, 0, sizeof(Type)*m)

된다

::std::vector<Type> t(n, 0);

그때

t = (Type*)realloc(t, sizeof(Type) * n2);

된다

t.resize(n2);

포인터를 함수에 전달하려면 대신

Foo(t)

사용하다

Foo(&t[0])

벡터는 스마트 한 C 배열이기 때문에 절대적으로 정확한 C ++ 코드입니다.


1
memset 줄은 memset (t, 0, sizeof (T) * n) ;? m 대신 n?
Raphael Mayer

1
@anthom 예. 정말해야합니다Type* t = static_cast<Type*>(malloc(n * sizeof *t));
라이언 이닝

2
C ++ 11 일 지금 사용하는 것 t.data()대신에&t[0]
knedlsepp

1
그런 다음 어떻게 삭제할 수 있습니까?
a3mlord

@ a3mlord : 무슨 뜻입니까? 범위를 벗어나면 사라집니다.
궤도의 경쾌한 경주

51

올바른 옵션은 아마도 당신을 위해 일하는 컨테이너를 사용하는 것 std::vector입니다.

new그리고 delete그들이 지정된 형식의 개체를 유지하기에 충분한 메모리를 할당하기 때문에, 크기를 조정할 수 없습니다. 주어진 유형의 크기는 절대 변경되지 않습니다. 있다 new[]delete[]있지만를 사용하는 이유는 좀처럼있다.

무엇 reallocC에서하는 일은 단지가 될 가능성이 malloc, memcpy그리고 free사용할 수있는 충분한 연속 사용 가능한 메모리가있는 경우 메모리 관리자가 영리한 뭔가를 할 수 있지만, 어쨌든.


6
@bodacydo : 증가하는 버퍼를 구현하지 말고 사용 std::vector하십시오. 필요할 때 자동으로 증가하고 원하는 경우 메모리를 미리 할당 할 수 있습니다 ( reserve()).
sharptooth

4
std :: vector <T>를 사용하십시오. 그게 목적입니다. C ++에서는 명시 적으로 리소스 관리 클래스를 작성하지 않는 한 new / delete / new [] / delete []를 직접 사용할 이유가 없습니다.
Puppy

4
@bod : 예, 할 수 있습니다. ( std::string
그런데도

1
예, 가능합니다. 문제 없습니다. 심지어 std::string그렇게 할 수 있습니다. 그런데 데이터 읽기도 단순화 될 수 있습니다. 데이터를 어떻게 읽고 있습니까?
Thomas

2
와 같은 소리가 나고 thevector.resize(previous_size + incoming_size)그 뒤에는 memcpy(또는 비슷한)로 &thevector[previous_size]가 필요합니다. 벡터의 데이터는 "배열처럼"저장됩니다.
Thomas

36

C ++에서 크기 조정은 생성자와 소멸자를 호출해야 할 가능성이 있기 때문에 어색합니다.

난 당신이 가질 수없는 이유를 C ++에서 근본적인 이유가 생각하지 않습니다 resize[]갈 운영자 new[]delete[]이 비슷한 일을했다 :

newbuf = new Type[newsize];
std::copy_n(oldbuf, std::min(oldsize, newsize), newbuf);
delete[] oldbuf;
return newbuf;

분명히 oldsize비밀 위치에서 검색 할 것 같은 그것에서이다 delete[], 및 Type피연산자의 유형에서 온 것입니다. resize[]유형이 복사 할 수없는 경우 실패합니다. 이는 해당 개체를 단순히 재배치 할 수 없기 때문에 정확합니다. 마지막으로, 위의 코드는 개체를 할당하기 전에 기본적으로 개체를 구성하므로 실제 동작으로는 원하지 않습니다.

newsize <= oldsize, 새로 축소 된 배열의 "끝을지나"객체에 대한 소멸자를 호출하고 다른 작업을 수행하지 않는 가능한 최적화가 있습니다. 표준은이 최적화가 필요한지 ( resize()벡터 일 때와 같이 ), 허용되지만 지정되지 않았 는지 , 허용되지만 구현에 따라 달라 지거나 금지 되는지 여부를 정의해야합니다 .

그런 다음 스스로에게 물어봐야 할 질문은 "이 기능을 제공하는 것이 실제로 유용 vector하며, 크기 조정이 가능한 컨테이너 (연속 메모리의 C ++ 98에서 생략 된 요구 사항)를 제공하도록 특별히 설계되었습니다. C ++ 03에서 수정 됨) C ++ 방식의 배열보다 더 적합합니까? "

대답은 "아니오"라고 널리 생각됩니다. 크기 조정 가능한 버퍼를 C 방식으로 수행하려면 malloc / free / reallocC ++에서 사용할 수 있는를 사용하십시오 . 크기 조정이 가능한 버퍼를 C ++ 방식으로 수행하려면 벡터 (또는 deque실제로 연속 스토리지가 필요하지 않은 경우)를 사용하십시오. new[]벡터와 같은 컨테이너를 구현하지 않는 한 원시 버퍼 를 사용하여 두 가지를 혼합하지 마십시오 .


0

다음은 realloc으로 간단한 벡터를 구현하는 std :: move 예제입니다 (한계에 도달 할 때마다 * 2). 아래에있는 사본보다 더 잘할 수있는 방법이 있으면 알려주세요.

다음으로 컴파일 :

  g++ -std=c++2a -O2 -Wall -pedantic foo.cpp

암호:

#include <iostream>
#include <algorithm>

template<class T> class MyVector {
private:
    T *data;
    size_t maxlen;
    size_t currlen;
public:
    MyVector<T> () : data (nullptr), maxlen(0), currlen(0) { }
    MyVector<T> (int maxlen) : data (new T [maxlen]), maxlen(maxlen), currlen(0) { }

    MyVector<T> (const MyVector& o) {
        std::cout << "copy ctor called" << std::endl;
        data = new T [o.maxlen];
        maxlen = o.maxlen;
        currlen = o.currlen;
        std::copy(o.data, o.data + o.maxlen, data);
    }

    MyVector<T> (const MyVector<T>&& o) {
        std::cout << "move ctor called" << std::endl;
        data = o.data;
        maxlen = o.maxlen;
        currlen = o.currlen;
    }

    void push_back (const T& i) {
        if (currlen >= maxlen) {
            maxlen *= 2;
            auto newdata = new T [maxlen];
            std::copy(data, data + currlen, newdata);
            if (data) {
                delete[] data;
            }
            data = newdata;
        }
        data[currlen++] = i;
    }

    friend std::ostream& operator<<(std::ostream &os, const MyVector<T>& o) {
        auto s = o.data;
        auto e = o.data + o.currlen;;
        while (s < e) {
            os << "[" << *s << "]";
            s++;
        }
        return os;
    }
};

int main() {
    auto c = new MyVector<int>(1);
    c->push_back(10);
    c->push_back(11);
}

-7

다음과 같이 시도하십시오.

typedef struct Board
{
    string name;
    int size = 0;
};

typedef struct tagRDATA
{
    vector <Board> myBoards(255);

    // Board DataBoard[255];
    int SelectedBoard;

} RUNDATA;

벡터가 불평합니다. 이것이 어레이, malloc 및 new가 여전히 존재하는 이유입니다.


12
그게 이유가 아닙니다. 그리고 나는 이것이 어떤 식 으로든 질문에 어떻게 대답하는지 보지 못합니다. 또는 typedefC를 작성하는 것처럼 모든 곳에서 사용하는 이유 .
Lightness Races in Orbit
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.