C ++ में आप 'realloc' कैसे करते हैं?


85

मैं reallocC ++ में कैसे कर सकता हूं ? यह भाषा से गायब लगता है - वहाँ है newऔर deleteनहीं resize!

मुझे इसकी आवश्यकता है क्योंकि जैसे ही मेरा कार्यक्रम अधिक डेटा पढ़ता है, मुझे इसे धारण करने के लिए बफर को पुनः लोड करने की आवश्यकता होती है। मुझे नहीं लगता deleteकि पुराने पॉइंटर को newआईएनजी और आईएनजी को एक नया, बड़ा, सही विकल्प है।


8
Stroustrup इस एक लंबे समय के लिए वापस, को देखने के उत्तर दिया: www2.research.att.com/~bs/bs_faq2.html#renew (यह एक अच्छी शुरुआत अगर आप क्लाइन के सी ++ पूछे जाने वाले प्रश्न के साथ C ++ के लिए नए हैं है।)
dirkgently

8
@Dirkgently द्वारा संदर्भित उत्तर अब यहाँ है: stroustrup.com/bs_faq2.html#renew - और क्लाइन के अक्सर पूछे जाने वाले प्रश्न अब सुपर का हिस्सा है: isocpp.org/faq
maxschlepzit

जवाबों:


54

उपयोग :: एसटीडी :: वेक्टर!

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-array है।


1
कंठस्थ रेखा को कंठस्थ न करें (t, 0, sizeof (T) * n) ;? n के बजाय मी?
राफेल मेयर

1
@ हां हां। यह वास्तव में होना चाहिए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[]लेकिन शायद ही कभी उन्हें उपयोग करने का एक कारण है।

क्या reallocसी में है सिर्फ एक होने की संभावना है malloc, memcpyऔर freeहालांकि स्मृति प्रबंधकों अगर वहाँ पर्याप्त सन्निहित मुक्त स्मृति उपलब्ध है कुछ चालाक करने के लिए अनुमति दी जाती है, वैसे भी।


6
@bodacydo: बढ़ते बफर को लागू न करें, बस उपयोग करें std::vector- जब जरूरत होगी तो यह स्वचालित रूप से बढ़ेगा और यदि आप चाहें तो मेमोरी को पूर्व-आवंटित कर सकते हैं ( reserve())।
शार्प्यूट

4
Std :: वेक्टर <T> का उपयोग करें। बस यही बात है। C ++ में, जब तक आप स्पष्ट रूप से संसाधन प्रबंधन कक्षाएं नहीं लिख रहे हैं, तब तक नए / डिलीट / नए [] / खुद को हटाने का उपयोग करने का कोई कारण नहीं है।
पिल्ला

4
@ बोड: हाँ, यह कर सकते हैं। (तो std::string, वैसे)
fredoverflow

1
हाँ, यह कर सकते हैं, कोई बात नहीं। यहां तक std::stringकि ऐसा भी कर सकते हैं। वैसे, एक मौका है कि आपके डेटा पढ़ने को भी सरल बनाया जा सकता है। आप अपना डेटा कैसे पढ़ रहे हैं?
थॉमस

2
लगता है thevector.resize(previous_size + incoming_size), के बाद memcpy(या समान) में &thevector[previous_size], क्या आप की जरूरत है। वेक्टर के डेटा को "एक सरणी की तरह" संग्रहीत करने की गारंटी है।
थॉमस

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 ++ तरीकों के साथ सरणियों से बेहतर फिट है? "

मुझे लगता है कि उत्तर को व्यापक रूप से "नहीं" माना जाता है। यदि आप रेजिस्टेबिल बफ़र्स को सी वे करना चाहते हैं, तो उपयोग करें malloc / free / realloc, जो सी ++ में उपलब्ध हैं। यदि आप सी + + तरीके से रेजिस्ट करने योग्य बफ़र्स करना चाहते हैं deque, तो वेक्टर का उपयोग करें (या , यदि आपको वास्तव में सन्निहित भंडारण की आवश्यकता नहीं है)। new[]कच्चे बफ़र्स के लिए उपयोग करके दोनों को मिलाने की कोशिश न करें , जब तक कि आप एक वेक्टर-जैसे कंटेनर को लागू न करें।


0

यहाँ एक std :: एक वास्तविक वेक्टर के साथ एक सरल वेक्टर को लागू करने का एक उदाहरण है (* हर बार जब हम सीमा को मारते हैं)। अगर मेरे पास नीचे दी गई कॉपी से बेहतर करने का कोई तरीका है, तो कृपया मुझे बताएं।

संकलन इस प्रकार है:

  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;

वेक्टर करेंगे शिकायत यही कारण है कि arrays, Malloc और नए अभी भी मौजूद हैं।


12
नहीं, ऐसा नहीं है। और मैं यह नहीं देखता कि यह किसी भी तरह से सवाल का जवाब कैसे देता है। या आप typedefहर जगह का उपयोग क्यों कर रहे हैं जैसे कि आप सी लिख रहे थे
लाइटवेट दौड़ें ऑर्बिट में
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.