2015-12-18 14 views
6

मैं C++ में गतिशील स्ट्रिंग सरणी बनाने की कोशिश कर रहा हूं।अपवाद त्रुटि: उल्लंघन उल्लंघन स्थान 0xDDDDDDDD

Exception thrown at 0x0FD670B6 (msvcp140d.dll) in Assignment4.exe: 0xC0000005: Access violation reading location 0xDDDDDDDD. 

यहाँ मेरी कोड है::

DynamicStringArray.h

#pragma once 
#include "stdafx.h" 
#include <string> 
#include <iostream> 

using namespace std; 

class DynamicStringArray 
{ 
public: 
    DynamicStringArray(); 
    DynamicStringArray(DynamicStringArray &array); 
    ~DynamicStringArray(); 
    int getSize(); 
    void displayContents(); 
    void addEntry(const string &addElement); 
    string getEntry(int index); 
    int deleteEntry(const string &deleteElement); 

private: 
    string *dynamicArray; 
    int size; 
}; 

DynamicStringArray.cpp

मैं यह त्रुटि प्राप्त जब कंसोल के लिए मेरी गतिशील स्ट्रिंग सरणी की सामग्री प्रदर्शित करने की कोशिश कर रहा
#include "stdafx.h" 
#include "DynamicStringArray.h" 
#include <string> 
#include <iostream> 

using namespace std; 

DynamicStringArray::DynamicStringArray() 
{ 
    dynamicArray = NULL; 
    size = 0; 
} 

DynamicStringArray::DynamicStringArray(DynamicStringArray &array) 
{ 
    if (dynamicArray != NULL) 
    { 
     size = 0; 
     delete [] dynamicArray; 
     dynamicArray = NULL; 
    } 

    size = array.getSize(); 
    dynamicArray = new string[size]; 
    for (int i = 0; i < size; i++) 
     dynamicArray[i] = array.dynamicArray[i]; 
} 

DynamicStringArray::~DynamicStringArray() 
{ 
    cout << "In destructor." << endl; 
    delete [] dynamicArray; 
    dynamicArray = NULL; 
} 

int DynamicStringArray::getSize() 
{ 
    return size; 
} 

void DynamicStringArray::displayContents() 
{ 
    if (size != 0) 
     for (int i = 0; i < size; i++) 
      cout << "Item-" << i << ": " << dynamicArray[i] << endl; 
    else 
     cout << "Array is empty." << endl; 
} 

void DynamicStringArray::addEntry(const string &addElement) 
{ 
    string *temp = new string[size + 1]; 
    for (int i = 0; i < size; i++) 
      temp[i] = dynamicArray[i]; 
    temp[size] = addElement; 
    size++; 
    delete [] dynamicArray; 
    dynamicArray = temp; 
    delete[] temp; 
} 

string DynamicStringArray::getEntry(int index) 
{ 
    if ((index >= 0) && (index < size)) 
    { 
     return dynamicArray[index]; 
    } 
    return NULL; 
} 

int DynamicStringArray::deleteEntry(const string &deleteElement) 
{ 
    if(size == 0) 
    { 
     return false; 
    } 

    for (int i = 0; i < size; i++) 
    { 
     if (dynamicArray[i] == deleteElement) 
     { 
      string *temp = new string[size - 1]; 
      for (int x = 0; x < size - 1; ++x) 
      { 
       if (x < i) 
        temp[x] = dynamicArray[x]; 
       else 
        temp[x] = dynamicArray[x + 1]; 
      } 

      delete[] dynamicArray; 
      dynamicArray = temp; 
      delete[] temp; 
      --size; 
      return true; 
     } 
    } 

    return false; 
} 

मुख्य:

int main() 
{ 
    DynamicStringArray dsArray1; 
    cout << "dsArray1.displayContents():" << endl; 
    dsArray1.displayContents(); // Should indicate array is empty 
    cout << "Display dsArray1.getSize()= " << dsArray1.getSize() << endl; 

    dsArray1.addEntry("Entry-A"); 
    dsArray1.displayContents(); 

    dsArray1.addEntry("Entry-B"); 
    dsArray1.displayContents(); 
    dsArray1.addEntry("Entry-C"); 
    dsArray1.displayContents(); 
    return 0; 
} 

क्या कोई मुझे बता सकता है कि मैं क्या गलत कर रहा हूं। मैं इस समस्या को कैसे ठीक करुं?

+2

किसी भी कारण से आपने 'std :: vector 'का उपयोग क्यों नहीं किया? – PaulMcKenzie

उत्तर

5

कृपया ध्यान दें कि यह सब std::vector<std::string> का उपयोग कर पहले से ही उपलब्ध है। std::vector कक्षा गतिशील सरणी कक्षा है जो सी ++ प्रदान करती है, और आपके लिए उपलब्ध चीज़ों के घर-निर्मित संस्करण बनाने का कोई कारण नहीं है।


यह कहकर, एक चमकदार मुद्दा यह है कि आपकी प्रतिलिपि निर्माता गलत है। dynamicArray अप्रारंभीकृत है, लेकिन आप इसे यहाँ का उपयोग करें:

if (dynamicArray != NULL)

इसकी कोई गारंटी नहीं dynamicArray है क्या मूल्य है। ठीक प्रतिलिपि निर्माता में कोड के इस पूरे ब्लॉक को हटाने के लिए है:

if (dynamicArray != NULL) 
{ 
    size = 0; 
    delete [] dynamicArray; 
    dynamicArray = NULL; 
} 

के बाद से प्रति निर्माता एक नया वस्तु निर्माण करती है, वहाँ एक शून्य सूचक के लिए "पूर्वपरीक्षण" करने के लिए कोई कारण नहीं है और इस तरह अनावश्यक काम करते हैं। याद रखें कि वस्तु मौजूद नहीं थी, इसलिए ऐसा करने के लिए प्रारंभिक कुछ भी नहीं है।


दूसरा मुद्दा यह है कि आप addEntry और deleteEntry कार्यों में एक delete [] temp; कॉल जारी करने जा रहे है। इन पंक्तियों को हटाएं, क्योंकि आप स्मृति को हटा रहे हैं जिसे आपने अभी dynamicArray पर असाइन किया है।


तीसरे मुद्दा यह है कि आप उपयोगकर्ता परिभाषित असाइनमेंट ऑपरेटर भूल रहे है। असाइनमेंट ऑपरेटर निम्नलिखित हस्ताक्षर है, और आप कार्यान्वयन प्रदान करने की आवश्यकता: इस समारोह के बिना

DynamicStringArray& operator=(const DynamicStringArray&); 

, बताए DynamicStringArray एक और DynamicStringArray करने के लिए एक मेमोरी लीक और स्मृति के दोहरे आवंटन रद्द करने का कारण जब दोनों वस्तुओं क्षेत्र से बाहर जाना होगा।

#include <algorithm> 
//... 
DynamicStringArray& DynamicStringArray::operator=(const DynamicStringArray& rhs) 
{ 
    DynamicStringArray temp(rhs); 
    std::swap(temp.dynamicArray, dynamicArray); 
    std::swap(temp.size, size); 
    return *this; 
} 

एक और मुद्दा यह है::

एक कार्यान्वयन copy/swap idiom उपयोग कर सकते हैं

string DynamicStringArray::getEntry(int index) 
{ 
    if ((index >= 0) && (index < size)) 
    { 
     return dynamicArray[index]; 
    } 
    return NULL; // <-- Undefined behavior if this is done 
} 

यह शून्य के साथ एक std::string वस्तु आवंटित करने के लिए अपरिभाषित व्यवहार है। या तो एक खाली स्ट्रिंग वापस करें, या अगर सूचकांक सीमा से बाहर है तो अपवाद फेंक दें।


अंत में, मैं अत्यधिक सुझाव है कि आप Rule of 3 को पढ़ने जब यह वर्गों है कि सही प्रतिलिपि अर्थ विज्ञान को लागू करना चाहिए डिजाइन करने के लिए आता है।

+2

'addEntry' में असाइनमेंट सभी' std :: string' हैं, इसलिए वे ठीक हैं ('ऑपरेटर =' को लागू करना अभी भी एक अच्छा विचार होगा)। पिछली पंक्ति 'हटाएं [] temp; ' –

+0

@ माइल्सबडनेक के साथ समस्या यह है कि मैंने' addEntry' और 'deleteEntry' दोनों के साथ समस्या को इंगित करने के लिए उत्तर अपडेट किया। – PaulMcKenzie

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