2013-03-18 6 views
10

एक शून्य पॉइंटर कास्टिंग करने के बाद भी, मुझे इसे संदर्भित करते समय संकलन त्रुटि मिल रही है। क्या कोई मुझे इस कारण बता सकता है।Dereference शून्य पॉइंटर

int lVNum = 2; 
void *lVptr; 
lVptr = (int*)&lVNum; 

printf("\nlVptr[60 ] is %d \n",lVptr[1]); 
+0

आप नहीं कर सकते हैं भिन्नता एक शून्य सूचक। वास्तविक संकलन त्रुटि क्या है? – MatthewD

+17

कोड की चार पंक्तियों में हमारे पास (ए) एक अनावश्यक कलाकार है, (बी) एक अवांछित सूचक का अवैध अपमान, और (सी) सीमा से बाहर अनिश्चित-व्यवहार। यह एक नया रिकॉर्ड हो सकता है। – WhozCraig

+0

आपको क्या कंपाइलर त्रुटियां मिलती हैं? वास्तविक त्रुटियों के बिना त्रुटियों के कारण आपको बताना मुश्किल है। –

उत्तर

12

printf("\nlVptr[60 ] is %d \n", *(int*)lVptr);

यह एक int के लिए सूचक को शून्य सूचक डाली और फिर इसे भिन्नता सही ढंग से होगा।

यदि आप इसे एक सरणी (एक के रूप में) के रूप में देखना चाहते हैं, तो आप थोड़ा बदसूरत ((int *)lVptr)[0] कर सकते हैं। [1] का उपयोग सीमा से बाहर है, और इसलिए कोई अच्छा विचार नहीं है (lVptr[60] के लिए ...)

4

यह क्योंकि क्या आप इसे के रूप में घोषित है कि अभी भी एक void* है। किसी भी सूचक को पूरी तरह से void* में परिवर्तित किया जा सकता है, ताकि कास्ट कुछ भी न करे और आपको void पर पॉइंटर के साथ छोड़ दिया गया हो।

आपको इसे int* के रूप में घोषित करने की आवश्यकता होगी।

void *some_ptr = /* whatever */; 
int *p = (int*)some_ptr; 
// now you have a pointer to int cast from a pointer to void 

ध्यान दें कि कलाकारों एक को int* भी अनावश्यक है इसी कारण से आप की जरूरत नहीं है के लिए (और नहीं चाहिए) सी

में

malloc के रिटर्न मान डाली void* को किसी भी अन्य सूचक प्रकार से और उसके रूप में परिवर्तित किया जा सकता है। मैंने यहां केवल स्पष्टता के लिए कलाकारों को जोड़ा, आपके कोड में आप बस लिखेंगे;

int *p = some_void_ptr; 

इसके अलावा, इस:

lVptr[1] 

गलत है। आपके पास एक int पर दो पॉइंटर नहीं है, दो नहीं। वह अव्यवस्था अपरिभाषित व्यवहार का कारण बनती है।

+0

+1 इस में छोड़ी गई एकमात्र चीज़ कास्ट है, जिसमें सी की आवश्यकता नहीं है। इसके अलावा, यह सब कुछ संबोधित करता है। – WhozCraig

+0

@WozozCraig: हाँ, मैं बस इसे जितना संभव हो उतना स्पष्ट होना चाहता था। मुझे लगता है कि मुझे इसका जिक्र करना चाहिए; यह भविष्य में मूर्ख 'malloc' कास्ट रोक सकता है। –

+0

हाँ। "// कास्ट की आवश्यकता नहीं है (या अनुशंसित), लेकिन आप जो कर रहे हैं उसे बढ़ाता है।" अभी भी अप-वोट = पी – WhozCraig

15

यह एक शून्य सूचक को हटाना समझ में नहीं आता है। संकलक उस स्मृति की व्याख्या कैसे करेगा जो सूचक इंगित कर रहा है? आप एक उचित प्रकार पहले सूचक कास्ट करने के लिए की जरूरत है:

int x = *(int*)lVptr; 
+1

मिला है यह सही जवाब होना चाहिए – thiagoh

+0

संकलक को स्मृति की व्याख्या करने की परवाह क्यों है? क्या यह उन परिचालनों तक नहीं है जिनके साथ मैं उस स्मृति को जोड़ता हूं? – Ungeheuer

+0

स्मृति में हेरफेर करने के लिए आपको '+' जैसे ऑपरेटरों का उपयोग करना होगा और उन ऑपरेटरों का व्यवहार किसी भी तरफ पूर्णांक प्रकारों पर निर्भर करता है। या यहां तक ​​कि बस कुछ स्मृति पढ़ने के लिए, आपको एक प्रकार निर्दिष्ट करने की आवश्यकता है ताकि संकलक जानता है कि कितने बाइट पढ़ने के लिए। यदि आप मेमोरी में मुफ्त फॉर्म एक्सेस चाहते हैं, तो पॉइंटर को 'uint8_t *' पर डालें। –

0

एक शून्य सूचक केवल एक शून्य (एक निश्चित नहीं है) के लिए एक सूचक है।

कुछ मामलों में उपयोगी। उदाहरण के लिए malloc() एक शून्य पॉइंटर ठीक से देता है क्योंकि यह एक अनिवार्य उद्देश्य के लिए स्मृति आवंटित करता है। कुछ फ़ंक्शन इसी प्रकार शून्य पॉइंटर्स को तर्क के रूप में ले सकते हैं क्योंकि उन्हें किसी स्थान के अलावा वास्तविक सामग्री की परवाह नहीं है।

ईमानदार होने के लिए, आपके द्वारा पोस्ट किए गए स्निपेट को बिल्कुल कोई समझ नहीं आता है, यह अनुमान भी नहीं लगा सकता कि आप क्या करने की कोशिश कर रहे थे।

0

तुम क्या करने की कोशिश कर रहा हो सकता है क्या का उदाहरण:

#include <stdio.h> 

int main() { 
    void *v; 
    unsigned long int *i = (unsigned long int *)v; 

    *i = 5933016743776703571; 

    size_t j = sizeof(i); 
    printf("There are %ld bytes in v\n", j); 

    size_t k; 
    for (k = 0; k < j; k++) { 
     printf("Byte %ld of v: %c\n", k, ((char *)v)[k]); 
    } 
} 

आउटपुट:

There are 8 bytes in v 
Byte 0 of v: S 
Byte 1 of v: T 
Byte 2 of v: A 
Byte 3 of v: C 
Byte 4 of v: K 
Byte 5 of v: O 
Byte 6 of v: V 
Byte 7 of v: R 
0

@ कोड-गुरु मैंने कोशिश की दृश्य स्टूडियो में यह संकलन करने। यह त्रुटि देता है - ऑब्जेक्ट पूर्ण करने के लिए अभिव्यक्ति एक सूचक होना चाहिए।

धन्यवाद टेपिक, जैसा कि आपने सुझाव दिया है, निम्नलिखित संकलन और सही परिणाम प्राप्त करता है।

#include<stdio.h> 

void main(){ 

printf("study void pointers \n"); 

int lvnum = 2; 
void *lvptr; 
lvptr = &lvnum; 
printf("\n lvptr is %d\n",((int *)lvptr)[0]); 


} 

लेकिन अगर मैं printf कोशिश (, ((int *) lVptr) "\ n lvptr% d \ n" [60]); यह संकलित करता है और चलता है लेकिन यादृच्छिक संख्या देता है।

बहुत सारे सुझाव, सभी सुझावों के लिए दोस्तों। क्षमा करें कि मैंने अनावश्यक रूप से कच्चे इंट पॉइंटर को शून्य सूचक दिया है और इसे अस्वीकार करने की उम्मीद है। हालांकि, जब मैं इसे अव्यवस्थित करना चाहता हूं तो मुझे इसे कास्ट करना चाहिए था।

स्निपेट का उद्देश्य: मेरे स्रोतों में मुझे क्लोकवर्क त्रुटि मिली जो इसी स्थिति के कारण हुई थी। इसके विपरीत कार्यक्रम न केवल संकलित बल्कि सही परिणाम भी दिया। कारण- यह एक निम्न स्तर का कोड (कोई ओएस नहीं है) जहां शून्य सूचक को आवंटित स्मृति पहले से ही 60 की गिनती तक आरक्षित है। लेकिन क्लोकवर्क उपकरण उस सीमा वाले फाइलों को पार्स करने में असमर्थ था जिसके परिणामस्वरूप त्रुटि हुई थी। मैंने बहुत सारे दिमागी तूफान किए और मूर्खतापूर्ण कुछ खत्म हो गया।

सौरभ

2

आप एक शून्य सूचक dereferencing नहीं कर सकते क्योंकि यह प्रकार नहीं है, पहले जरूरत यह डाली और फिर अपसंदर्भन को * (int *) lVptr

int lVNum = 2; 
void *lVptr; 
lVptr = &lVNum; 

printf("\nlVptr[60 ] is %d \n",*(int *)lVptr); 
संबंधित मुद्दे