6

संकलक निम्नलिखित कोड पर क्रम segfault फेंकता का उपयोग कर इसके निर्माण के बाद अपने काम पर विभाजन गलती का कारण बनता है:स्ट्रिंग मान युक्त struct गतिशील स्मृति आवंटन

#include <iostream> 
#include <string> 
using namespace std; 

struct Node{ 
    int data; 
    void *next; 
    string nodeType; 
}; 

Node* initNode(int data){ 
    Node *n = (Node*)malloc(sizeof(Node)); 
    n->data = data; 
    n->next = NULL; 
    n->nodeType = "Node"; //if this line is commented it works else segfault 
    return n; 
} 

int main() { 
    Node *n1 = initNode(10); 
    cout << n1->data << endl; 
} 

किसी कृपया समझा क्यों स्ट्रिंग काम एक struct के अंदर काम नहीं करता है जो गतिशील रूप से आवंटित किया गया है जहां स्थिर आवंटन के मामले में यह क्यों काम करता है?

निम्नलिखित तरीके के रूप में जहां यह काम करता है:

Node initNode(string data){ 
    Node n; 
    n.data = data; //This works for node creation statically 
    n.next = NULL; 
    n.nodeType = "Node"; //and even this works for node creation statically 
    return n; 
} 

और फिर मुख्य समारोह में:

int main() { 
    Node n2 = initNode("Hello"); 
    cout << n2.data << endl; 
} 
+1

'malloc' बस स्मृति आवंटित करता है, यह * ऑब्जेक्ट उदाहरण * निर्माण नहीं करता है, जिसका अर्थ है 'स्ट्रिंग' कन्स्ट्रक्टर नहीं कहा जाता है। –

+2

अंगूठे का सामान्य नियम: सी ++ में सी के 'मॉलोक' का उपयोग न करें, 'नया' का उपयोग करें, और वास्तव में यदि संभव हो तो 'new' का उपयोग न करें, और 'make_shared' या' std :: unique_ptr' (C + +11) –

उत्तर

8

यह काम नहीं करता क्योंकि आप वास्तव में एक Node उदाहरण में निर्माण नहीं है स्मृति जो आप malloc

आप new बजाय का उपयोग करना चाहिए:

Node *n = new Node{}; 

malloc केवल स्मृति आबंटित करता है, यह पता नहीं क्या एक वर्ग है या कैसे एक दृष्टांत गया है। आपको आमतौर पर इसे C++ में उपयोग नहीं करना चाहिए।

new मेमोरी और आवंटित करता है कक्षा का एक उदाहरण बनाता है।

+0

हे या यह काम करता है: नोड * एन = नया नोड(); लेकिन मैंने सोचा कि मॉलोक वास्तव में उदाहरण बनाकर स्मृति आवंटित करेगा? क्या यह सच नहीं है? क्या आप कृपया "नया" और "मॉलोक" करने और इसे कब उपयोग करने के बीच अंतर को इंगित कर सकते हैं? – Dhwanit

+0

मैंने अधिक जानकारी के साथ अपना जवाब संपादित किया। – TartanLlama

+0

हाँ ठीक है! धन्यवाद! अच्छी तरह से मुझे वास्तव में एक एहसास हुआ कि स्ट्रिंग के कन्स्ट्रक्टर को कॉल किया जाएगा जब मैंने मैलोक किया था क्योंकि यह स्ट्रिंग था और स्ट्रिंग नहीं * – Dhwanit

4

कोई जगह नहीं है, जहां std :: स्ट्रिंग कंस्ट्रक्टर निष्पादित किया गया है।

आप का उपयोग करना चाहिए नई

example *e = new example; 

या नियुक्ति नई

void *example_raw = malloc(sizeof(example)); 
example *e = new(example_raw) example; 
+0

धन्यवाद yup यह इस तरह से भी काम करता है! :) – Dhwanit

1

string C++ में एक वर्ग है और स्ट्रिंग वस्तुओं new बजाय नीचे के रूप में malloc का उपयोग बनाने के लिए।

Node *n = new Node{}; 
3
Node *n = (Node*)malloc(sizeof(Node)); 

यह डाली बकवास है। आप संकलनकर्ता को यह बताने के लिए नहीं कह सकते कि आपके द्वारा आवंटित डेटा का एक हिस्सा वैध Node ऑब्जेक्ट है और फिर इसे कुशलतापूर्वक उपयोग करता है।

+0

हाँ ठीक है!अच्छी तरह से मुझे वास्तव में एक एहसास हुआ कि स्ट्रिंग के कन्स्ट्रक्टर को कॉल किया जाएगा जब मैंने मॉलोक किया था क्योंकि यह स्ट्रिंग था और स्ट्रिंग नहीं * नोड के अंदर – Dhwanit

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