2017-02-22 21 views
7

मान लें कि मेरे पास सी पुस्तकालय एपीआई फ़ंक्शन है जो पॉइंटर्स के पैरामीटर के रूप में पॉइंटर लेता है। हालांकि जब से मैं सी ++ में प्रोग्रामिंग कर रहा हूं, मैं गतिशील स्मृति से निपटने के लिए स्टडी वेक्टर का लाभ लेना चाहता हूं। मैं पॉइंटर के सूचक में वेक्टर के वेक्टर को कुशलतापूर्वक कैसे परिवर्तित कर सकता हूं? अभी मैं इसका उपयोग कर रहा हूँ।पॉइंटर

#include <vector> 

/* C like api */ 
void foo(short **psPtr, const int x, const int y);  

int main() 
{ 
    const int x = 2, y = 3; 
    std::vector<std::vector<short>> vvsVec(x, std::vector<short>(y, 0)); 
    short **psPtr = new short*[x]; 

    /* point psPtr to the vector */ 
    int c = 0; 
    for (auto &vsVec : vvsVec) 
     psPtr[c++] = &vsVec[0]; 

    /* api call */ 
    foo(psPtr, x, y);   

    delete[] psPtr; 
    return 0; 
} 

क्या यह लक्ष्य प्राप्त करने का सबसे अच्छा तरीका है? क्या मैं इस मामले में इटरेटर या कुछ std विधि का उपयोग करके "नई हटाएं" चीज़ से छुटकारा पा सकता हूं? अग्रिम में धन्यवाद।

संपादित करें: उत्तर के अनुसार अब मैं इस संस्करण का उपयोग सी कोड के साथ इंटरफेस करने के लिए कर रहा हूं। मैं इसे यहां पोस्ट कर रहा हूं।

#include <vector> 

/* C like api */ 
void foo(short **psPtr, const int x, const int y);  

int main() 
{ 
    const int x = 2, y = 3; 
    std::vector<std::vector<short>> vvsVec(x, std::vector<short>(y, 0)); 
    std::vector<short*> vpsPtr(x, nullptr); 

    /* point vpsPtr to the vector */ 
    int c = 0; 
    for (auto &vsVec : vvsVec) 
     vpsPtr[c++] = vsVec.data(); 

    /* api call */ 
    foo(vpsPtr.data(), x, y);   

    return 0; 
} 

मेरे जैसे अधिक सी ++ दिखता है। सबको धन्यवाद!

+3

ड्रॉप एक वेक्टर के स्तर और उस फ्लैट वेक्टर के पहले तत्व के लिए सूचक का पता ले। – rubenvb

+0

केवल इसे अच्छी लगती है, आप एक सदिश के साथ psPtr को प्रतिस्थापित कर सकते हैं, और इसे एल्गोरिदम में कुछ फ़ंक्शन के साथ सेट कर सकते हैं। – BlueWanderer

+0

एपीआई फ़ंक्शन को या तो आकार पैरामीटर की आवश्यकता होती है या यह सम्मेलन है कि एक शून्य सूचक अंतिम तत्व को इंगित करता है, इस स्थिति में आपको अंत में 'nullptr' जोड़ना होगा। –

उत्तर

4

क्या यह लक्ष्य प्राप्त करने का सबसे अच्छा तरीका है?

यदि आप सुनिश्चित हैं कि वेक्टर के वेक्टर psPtr से अधिक हो जाएंगे, तो हाँ। अन्यथा, आप जोखिम को चलाते हैं कि psPtr में अमान्य पॉइंटर्स होंगे।

क्या मैं इस मामले में इटरेटर या कुछ std विधि का उपयोग करके "नई हटाएं" चीज़ से छुटकारा पा सकता हूं?

हां।

std::vector<short*> psPtr(vvsVec.size()); 

और फिर सी एपीआई समारोह के लिए कॉल में &psPtr[0] का उपयोग करें: मैं का उपयोग कर सुझाव देते हैं। इससे आपके कोड से मेमोरी प्रबंधन का बोझ हटा दिया जाता है।

foo(&psPtr[0]);   
+0

यह बहुत साफ दिखता है। पहले पॉइंटर के वेक्टर के बारे में कभी नहीं सोचा था। धन्यवाद! – yc2986

+0

@ yc2986, आपका स्वागत है। –

+0

@ yc2986: पॉइंटर्स का वेक्टर आमतौर पर एक विरोधी पैटर्न होता है। यदि आपने कभी ऐसा करने का विचार नहीं किया है, तो यह वास्तव में एक अच्छी बात है। – IInspectable

3
std::vector<short*> vecOfPtrs; 
for (auto&& vec : vvsVec) 
    vecOfPtrs.push_back(&vec[0]); 

foo(&vecOfPtrs[0]); 
+0

चूंकि आप समय से पहले कंटेनर 'vecOfPtrs' के आकार को जानते हैं, तो आपको इसे वास्तव में उस आकार में प्रारंभ करना चाहिए। यह संभावित स्मृति स्थानान्तरण, और आकार बदलने के कारण संभावित अपवादों को रोकता है। – IInspectable

+0

क्यों '& vec [0]' और 'vec.data()'? मैं 'vec का उपयोग करने के कम से कम 3 कारणों के बारे में सोच सकता हूं।डेटा() '' 'और vec [0]', और 'vecdata()' 'vec [0] 'का उपयोग करने के लिए शून्य। (खाली वैक्टर, 'वेक्टर ',' std :: addressof' मुद्दों को कम करने में, – Yakk

+0

@Yakk मुझे लगता है कि पुरानी आदतें C++ 03 से कठिन होती हैं। 'vec.data()' बेहतर है। हालांकि, आपका पहला कारण बिल्कुल अच्छा नहीं है क्योंकि 'vec.data()' को रिक्त वेक्टर के लिए भी 'vec [0] 'वापस करना चाहिए, और सी ++ मानक एक-अतीत के अंत को संबोधित करने की अनुमति देता है एक सरणी का – rlbond

संबंधित मुद्दे