2012-01-15 27 views
8

मैं इस विषय के बारे में खोज रहा था और मैं एक एसटीडी करने के लिए एक सरणी [] परिवर्तित करने के लिए कई मायनों :: वेक्टर, का उपयोग कर की तरह पाया में एक सरणी को कॉपी करना:एक std :: वेक्टर

assign(a, a + n) 

या, में प्रत्यक्ष निर्माता:

std::vector<unsigned char> v (a, a + n); 

उन मेरी समस्या का समाधान है, लेकिन अगर यह संभव है (और सही) है मैं सोच रहा हूँ करने के लिए:

myvet.resize(10); 
memcpy(&myvet[0], buffer, 10); 

मैं सोच रहा हूँ इस वजह से मैं निम्नलिखित कोड है:

IDiskAccess::ERetRead nsDisks::DiskAccess::Read(std::vector<uint8_t>& bufferRead, int32_t totalToRead) 
{ 
    uint8_t* data = new uint8_t[totalToRead]; 
    DWORD totalRead; 
    ReadFile(mhFile, data, totalToRead, &totalRead, NULL); 
    bufferRead.resize(totalRead); 
    bufferRead.assign(data, data + totalRead); 
    delete[] data; 

    return IDiskAccess::READ_OK; 
} 

और मैं क्या करना चाहते हैं:

IDiskAccess::ERetRead nsDisks::DiskAccess::Read(std::vector<uint8_t>& bufferRead, int32_t totalToRead) 
{ 
    bufferRead.resize(totalToRead); 
    DWORD totalRead; 
    ReadFile(mhFile, &bufferRead[0], totalToRead, &totalRead, NULL); 
    bufferRead.resize(totalRead); 

    return IDiskAccess::READ_OK; 
} 

(मैं ReadFile फ़ंक्शन की त्रुटि उपचार को हटा दिया है पद सरल करने के लिए)।

यह काम कर रहा है, लेकिन मुझे डर है कि यह सुरक्षित नहीं है। मेरा मानना ​​है कि यह ठीक है, क्योंकि वेक्टर द्वारा उपयोग की जाने वाली स्मृति निरंतर है, लेकिन मैंने कभी इस तरह वैक्टर का उपयोग करके किसी को नहीं देखा है।

क्या इस तरह के वैक्टरों का उपयोग करना सही है? क्या कोई और बेहतर विकल्प है?

उत्तर

8

हाँ यह std::vector सी ++ मानक गारंटी के साथ सुरक्षित है कि तत्वों को संगत स्मृति स्थानों पर संग्रहीत किया जाएगा।

सी ++ 11 मानक:

23.3.6.1 कक्षा templatevector सिंहावलोकन [vector.overview]

वेक्टर एक अनुक्रम कंटेनर कि रैंडम एक्सेस iterators समर्थन करता है। इसके अलावा, इसके समर्थन (amortized) निरंतर समय अंत में सम्मिलित करें और मिटाएं; मध्य में रैखिक समय डालें और मिटाना। भंडारण प्रबंधन स्वचालित रूप से संभाला जाता है, हालांकि ई एफएफआई दक्षता में सुधार के लिए संकेत दिए जा सकते हैं। एक वेक्टर के तत्वों को समीपवर्ती जमा हो जाती है, जिसका अर्थ है है कि IFV avector whereT कुछ प्रकार bool के अलावा अन्य है, तो यह पहचान का अनुसरण करता है & वी [n] == & वी [0] + n all0 के लिए < = n < v .size()।

1

अपना आकार बदलें पहले, और यह ठीक काम करना चाहिए।

vector<int> v; 
v.resize(100); 
memcpy(&v[0], someArrayOfSize100, 100 * sizeof(int)); 
+3

वह * पहले * आकार बदलता है (उसके फ़ंक्शन की पहली पंक्ति देखें)। – celtschk

+1

मैं यह नहीं कह रहा था कि वह ऐसा करने में असफल रहा। मैं बस इसके महत्व पर जोर दे रहा था। – TheBuzzSaw

+1

आपके पास इसका मतलब यह नहीं था * लेकिन * आपने किया था। – celtschk

2

vector में स्मृति समीप आवंटित होने की गारंटी है, और अहस्ताक्षरित चार पॉड है, इसलिए यह पूरी तरह से इसे में memcpy (यह मानते हुए आप अधिक कॉपी नहीं है की तुलना में आप निश्चित रूप से, आवंटित) के लिए सुरक्षित है।

1

हां, memcpy का उपयोग कर समाधान सही है; vector द्वारा आयोजित बफर संगत है। लेकिन यह काफी प्रकार से सुरक्षित नहीं है, इसलिए assign या std::copy पसंद करें।

5

हां, ऐसा करना ठीक है। &myvet[0] के बजाय myvet.data() करना चाहें तो यह आपके लिए बेहतर दिखता है, लेकिन दोनों का एक ही प्रभाव है।इसके अलावा, यदि परिस्थितियों की अनुमति है, तो आप इसके बजाय std::copy का उपयोग कर सकते हैं और अधिक प्रकार की सुरक्षा और अन्य सभी C++ मानक लाइब्रेरी उपहारों का उपयोग कर सकते हैं।

भंडारण जो vector उपयोग करता है वह संगत होने की गारंटी देता है, जो इसे बफर या अन्य कार्यों के उपयोग के लिए उपयुक्त बनाता है।

जब तुम सूचक आप data या &v[0] से प्राप्त कर प्रयोग कर रहे हैं क्योंकि vector उन कार्यों में से एक पर अपने बफर आकार बदलने और गलत हो सकते हैं सुनिश्चित करें कि आप (इस पर push_back, आदि बुला रूप में इस तरह) को संशोधित नहीं vector बनाओ सूचक

3

यह दृष्टिकोण सही है, यह केवल वेक्टर पर निर्भर करता है जो मानक द्वारा आवश्यक संगत स्मृति वाले पर निर्भर करता है। मेरा मानना ​​है कि सी ++ 11 में वेक्टरों में एक नया data() सदस्य फ़ंक्शन है जो बफर को पॉइंटर देता है। यह भी ध्यान रखें कि 'memcpy के मामले में आपको बाइट्स में आकार को पास करने की आवश्यकता नहीं है, ईर के आकार

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