जिज्ञासा से बाहर, मैंने लिनक्स पर जीसीसी का उपयोग करके आपके कोड का परीक्षण किया, और इसकी अपेक्षा से कहीं अधिक मजबूत (सभी के बाद, लिखना लंबाई 0 के वर्ण बफर को डेटा अपरिभाषित व्यवहार है ... मैं को क्रैश करने की उम्मीद करता हूं)।
अपने कोड के अपने संशोधन है:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *p;
p = malloc(sizeof(char)*0);
printf("Hello Enter some without spaces :\n");
scanf("%s",p);
char *q;
q = malloc(sizeof(char)*0);
printf("Hello Enter more data without spaces :\n");
scanf("%s",q);
printf("The first string is '%s'\n",p);
printf("The second string is '%s'\n",q);
}
मेरी पहली सोचा है कि आप तथ्य यह है कि आप केवल एक ही स्मृति स्थान में डेटा पढ़ रहे हैं द्वारा बचाया जा सकता था - अगर आप दो बफ़र्स उपयोग करते हैं, दूसरा पहले के ऊपर लिख सकता है ... इसलिए मैं इनपुट और आउटपुट वर्गों में कोड को तोड़ दिया:
Hello Enter some without spaces :
asdf
Hello Enter more data without spaces :
tutututu
The first string is 'asdf'
The second string is 'tutututu'
पहले बफर ओवरराइट कर दिया गया था, तो हम देखना होगा
The first string is 'tutututu'
The second string is 'tutututu'
तो ऐसा नहीं है।
फिर [लेकिन यह कितना डेटा आप प्रत्येक बफर में पैक पर निर्भर करता है ... नीचे देखें], मैं दोनों चर में डेटा की एक पागल राशि चिपकाया:
perl -e 'print "c" x 5000000 . "\n" ' | xsel -i
(इस के 4 एमबी डाल 'सी कॉपी बफर में)। मैंने इसे पहले और दूसरे स्कैनफ कॉल दोनों में चिपकाया। कार्यक्रम ने इसे विभाजन खंड के बिना लिया।
भले ही मेरे पास सेगमेंटेशन गलती न हो, फिर भी पहला बफर ओवरराइट हो गया। मैं इसे नहीं बता सका क्योंकि स्क्रीन पर इतना डेटा उड़ रहा था।यहाँ कम डेटा के साथ एक रन है:
$ ./foo
Hello Enter some without spaces :
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Hello Enter more data without spaces :
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
The first string is 'aaaaaaaaaaaa'
The second string is 'ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc'
aaaaaaaaaaaa के बाद एक छोटे से ग्लिफ़, जिसके कारण मेरी टर्मिनल एक यूनिकोड चरित्र है कि यह प्रदर्शित नहीं कर सकता का प्रतिनिधित्व करता था। यह अधिलेखित डेटा के विशिष्ट है: आपको पता नहीं है कि आपके डेटा को ओवरराइट करने जा रहा है ... यह अपरिभाषित व्यवहार है, इसलिए आप नाक राक्षसों के लिए प्रवण हैं।
नीचे की रेखा यह है कि जब आप स्मृति को लिखते हैं कि आपने स्पेस आवंटित नहीं किया है (या तो स्पष्ट रूप से मॉलोक या सरणी के साथ सरणी का उपयोग करके), तो आप आग से खेल रहे हैं। जल्दी या बाद में, आप स्मृति को ओवरराइट कर देंगे और खुद को दुःख के सभी प्रकार का कारण बनेंगे।
असली पाठ यहां है कि सी की जांच करने के लिए सीमा नहीं करता है। यह खुशी से आपको उस स्मृति को लिखने देगा जो आपके पास नहीं है। आप इसे पूरे दिन कर सकते हैं। आपका प्रोग्राम सही ढंग से चल सकता है, और ऐसा नहीं हो सकता है। यह क्रैश हो सकता है, यह दूषित डेटा वापस लिख सकता है, या यह तब तक काम कर सकता है जब तक कि आप परीक्षण करते समय उपयोग किए गए एक से अधिक बाइट में स्कैन न करें। यह परवाह नहीं है, तो आपको करना है।
malloc(0)
का मामला बस this question का एक विशेष मामला है।
विषय बंद करें .. लेकिन मॉलोक रिटर्न डालने के लिए यह एक अच्छा अभ्यास नहीं है .. देखें [यह] (http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – Krishnabhadra
सी आपके द्वारा सौंपा गया बफर ओवर-रनिंग के विरुद्ध आपकी सुरक्षा नहीं करता है - आपको यह करने के लिए सावधान रहना होगा अन्यथा आप किसी और की स्मृति पर टंपल करेंगे। – Rup
संभावित डुप्लिकेट [मैलोक (0) विंडोज में एक गैर-शून्य पता क्यों देता है?] (Http://stackoverflow.com/questions/9723030/why-does-malloc0-return-a-non-null-address- इन-विंडोज़) – Jay