2008-09-19 16 views
6

में पॉइंटर्स के साथ int मैट्रिक्स मुझे मेमोरी लीक बनाने के बिना इंट मैट्रिक्स बनाने के साथ कुछ समस्याएं आ रही हैं। मैं read_matrix() के माध्यम से किसी भी आकार में गतिशील (वैश्विक) मैट्रिक्स बनाने में सक्षम होना चाहता हूं। लेकिन फिर मैं बाद में स्मृति को मुक्त करने में सक्षम होना चाहता हूं। तो मेरी मुख्य विधि में दूसरे printf को बस त्रुटि में परिणाम होना चाहिए क्योंकि इसमें इसे आवंटित कोई स्मृति नहीं होनी चाहिए। मैं इसे बनाने के बारे में कैसे जाऊं?सी-मेमोरी आवंटन भ्रम

int**  first_matrix; 
int**  second_matrix; 
int**  result_matrix; 

int** read_matrix(int size_x, int size_y) 
{ 
    int** matrix; 
    matrix = calloc(size_x, sizeof(int*)); 
    for(int i = 0;i<size_x;i++) { 
     matrix[i] = calloc(size_y, sizeof(int)); 
    } 
    for(int i = 0;i<size_x;i++) { 
     for(int j = 0;j<size_y;j++) { 
      matrix[i][j] = i*10+j; 
     } 
    } 
    return matrix; 
} 

int main(int stackc, char** stack) 
{ 
    first_matrix = read_matrix(10,10); 
    printf("9:3 %d - 4:6 %d \n", first_matrix[9][3], first_matrix[4][6]); 
    free(*first_matrix); 
    free(first_matrix); 
    printf("9:3 %d - 4:6 %d \n", first_matrix[9][3], first_matrix[4][6]); 
} 

उत्तर

9

सिर्फ इसलिए कि स्मृति मुक्त हो गई है इसका मतलब यह नहीं है कि आप इसका उपयोग नहीं कर सकते हैं! बेशक, यह बहुत खराब इसे मुक्त करने के बाद इसे एक्सेस करने का विचार है, लेकिन यही कारण है कि यह आपके उदाहरण में काम करता है।

ध्यान दें कि free(*first_matrix) केवल नि: शुल्क first_matrix[0], अन्य सरणी नहीं। आप शायद आखिरी सरणी को इंगित करने के लिए किसी प्रकार का मार्कर चाहते हैं (जब तक आप बाहरी सरणी को मुक्त नहीं करते हैं, तब तक आप हमेशा जानते होंगे कि आपने कितने आंतरिक सरणी आवंटित की हैं)।की तरह कुछ:

int** read_matrix(int size_x, int size_y) 
{ 
    int** matrix; 
    matrix = calloc(size_x, 1+sizeof(int*)); // alloc one extra ptr 
    for(int i = 0;i<size_x;i++) { 
     matrix[i] = calloc(size_y, sizeof(int)); 
    } 
    matrix[size_x] = NULL; // set the extra ptr to NULL 
    for(int i = 0;i<size_x;i++) { 
     for(int j = 0;j<size_y;j++) { 
      matrix[i][j] = i*10+j; 
     } 
    } 
    return matrix; 
} 

तब जब आप उन्हें मुक्त कराने रहे हैं:

// keep looping until you find the NULL one 
for(int i=0; first_matrix[i] != NULL; i++) { 
    free(first_matrix[i]); 
} 
free(first_matrix); 
+0

ऐसा लगता है कि मैट्रिक्स तक लूपिंग [i]! = NULL काम करता है भले ही मैं अंतिम सूचक को न्यूल पर सेट न करूं, क्या यह संयोग/कुछ और बुरा है? – Fredrik

+0

यदि आप एक अतिरिक्त पॉइंटर आवंटित करते हैं और इसे सेट नहीं करते हैं, तो यह ओएस के आधार पर * डिफ़ॉल्ट * डिफ़ॉल्ट हो सकता है (विंडोज़ शून्य आवंटित स्मृति, यूनिक्स नहीं करता है)। यदि ऐसा नहीं है, तो आप आवंटित सरणी के अंत को बंद कर देंगे और जब तक आप एक पूर्ण सूचक या (अधिक संभावना) क्रैश को मारने के लिए चीजें मुक्त नहीं करते हैं। –

+1

कॉलोक हमेशा स्मृति को शून्य पर सेट करता है। – quinmars

2

आप व्यक्तिगत रूप से प्रत्येक पंक्ति को मुक्त करने की जरूरत है:


void free_matrix(int **matrix, int size_x) 
{ 
    for(int i = 0; i < size_x; i++) 
     free(matrix[i]); 
    free(matrix); 
} 
+0

आप सी – terminus

+2

में चक्र के लिए एक चर घोषित नहीं कर सकते हैं, आप सी 99 में कर सकते हैं, लेकिन आपका कोड बैक पोर्टेबल नहीं होगा। –

0

आप केवल first_matrix की पहली पंक्ति (या स्तंभ) को मुक्त कर दिया।

void free_matrix(int **matrix, int rows) 
{ 
    int i; 
    for(i=0; i<rows; i++) 
    { 
     free(matrix[i]); 
    } 
    free(matrix); 
} 

आप इसे पंक्ति और स्तंभ गिनती है स्टोर करने के लिए एक struct में मैट्रिक्स बनाने के लिए चाहते हो सकता है: इस तरह एक और समारोह लिखें।

1

स्मृति को मुक्त करने से यह दूर नहीं जाता है, इसका मतलब यह है कि एक और आवंटन स्मृति के समान हिस्से को पकड़ सकता है। जो भी आप इसमें डालते हैं वह तब तक वहां रहेगा जब तक कि कुछ और इसे ओवरराइट नहीं करता।

इसके अलावा, आप आवंटित सब कुछ मुक्त नहीं कर रहे हैं। आप केवल पॉइंटर्स और पहली पंक्ति की सरणी मुक्त कर रहे हैं। लेकिन अगर आप सबकुछ सही ढंग से मुक्त करते हैं, तो भी आपको वही प्रभाव होगा।

यदि आप "बस त्रुटि" बनाना चाहते हैं तो आपको उस स्मृति को इंगित करने की आवश्यकता है जो आपकी प्रक्रिया से संबंधित नहीं है। आप वैसे भी ऐसा क्यों करना चाहते हैं?

+0

मैं बस यह दिखाने के लिए ऐसा करना चाहता था कि स्मृति मुक्त थी, लेकिन अब पता चला कि गलती मेरी सोच में थी, मैं ओएसओएस एक्स के बाद से वाल्ग्रिंड नहीं चला सकता और यह देखने का एक तरीका चाहता था कि मैंने वास्तव में इसे मुक्त किया है या नहीं – Fredrik

0

मैं बस त्रुटि उत्पन्न करने की कोशिश करने के विरोध में, unfree'd स्मृति को ट्रैक करने के लिए valgrind का उपयोग करने की सलाह देते हैं। यह कई अन्य सामानों के लिए भी चट्टानों।

सैम

+0

मैं ओएस एक्स पर हूं इसलिए मैं valgrind नहीं चला सकता, अन्यथा मैं:/ मैक पर काम करने वाले किसी भी विकल्प को जानता हूं? – Fredrik

0

आप मेमोरी लीक हो रही है क्योंकि आप वें पंक्तियों को मैट्रिक्स की पहली पंक्ति और पंक्तियों की सूची, लेकिन 1 में से कोई भी मुक्त कराने रहे हैं। आपको एक लूप में मुफ्त कॉल करने की आवश्यकता है।

वहाँ विकल्प के एक जोड़े, तथापि हैं: - sizeof (int *) पंक्तियों + पंक्तियों कॉलम * sizeof (int) बाइट्स आवंटित और पंक्ति संकेत के लिए पहली बाइट का उपयोग। इस तरह, आपके पास केवल स्मृति का एक हिस्सा है (और यह आवंटन पर भी आसान है) - पंक्तियों की संख्या वाले एक स्ट्रक्चर का उपयोग करें। फिर आप पूरी तरह से पंक्ति सूची से बच सकते हैं (स्मृति को सहेज सकते हैं)। केवल नकारात्मक पक्ष यह है कि आपको मैट्रिक्स को संबोधित करने के लिए फ़ंक्शन, मैक्रो या कुछ गन्दा नोटेशन का उपयोग करना होगा।

यदि आप दूसरे विकल्प के साथ जाते हैं, तो आप किसी भी सी 99 कंपाइलर में इस तरह की संरचना का उपयोग कर सकते हैं, और फिर केवल स्मृति के एक ब्लॉक को आवंटित करना होगा (आकार संख्याएं * आकार (int) + sizeof (int)) :

struct matrix { 
    int rows; 
    int data[0]; 
} 
0

अवधारणा तुम यहाँ याद कर रहे हैं, यह है कि हर calloc के लिए, वहाँ एक मुक्त होना चाहिए है। और वह निःशुल्क कॉलोक से वापस दिए गए सूचक पर लागू होना चाहिए।

मैं तुम्हें एक समारोह (नामित delete_matrix) बनाने संकेत है कि आप यहाँ

के लिए में आवंटित के सभी मुक्त करने के लिए एक पाश का उपयोग करता है की सलाह देते हैं (int i = 0; मैं < size_x; i ++) { मैट्रिक्स [i] = कॉलोक (size_y, sizeof (int)); }

फिर, एक बार ऐसा करने के बाद, इस द्वारा आवंटित सूचक को मुक्त करें।

मैट्रिक्स = कॉलोक (आकार_एक्स, आकार (int *));

जिस तरह से आप अब कर रहे हैं,

मुफ्त (* first_matrix); मुफ्त (first_matrix);

वह नहीं करेगा जो आप करना चाहते हैं।

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