2015-05-28 9 views
5

मैं valgrind का उपयोग कर नीचे इस कोड को फ़ाइल test.c सत्यापित करने के लिए कोशिश कर रहा हूँ, जब मैं जीसीसी test.c -ओ परीक्षण कर रहा अनुवर्ती त्रुटिवेलग्रिंड त्रुटि M64 M32

Syscall param write(buf) points to uninitialised byte(s) 
==22765== at 0x4F22870: __write_nocancel (syscall-template.S:81) 
==22765== by 0x4EB0002: [email protected]@GLIBC_2.2.5 (fileops.c:1261) 
==22765== by 0x4EB14DB: [email protected]@GLIBC_2.2.5 (fileops.c:538) 
==22765== by 0x4EB0D5F: [email protected]@GLIBC_2.2.5 (fileops.c:165) 
==22765== by 0x4EA4B0F: [email protected]@GLIBC_2.2.5 (iofclose.c:59) 
==22765== by 0x400986: main (in /home/grados-sanchez/git/merkle-codigos-C/test) 
==22765== Address 0x4025770 is not stack'd, malloc'd or (recently) free'd 
==22765== Uninitialised value was created by a stack allocation 
==22765== at 0x4007E2: node_write (in /home/grados-sanchez/git/merkle-codigos-C/test) 

मिल लेकिन जब मैं जीसीसी चलाने test.c -o परीक्षण और फिर valgrind मुझे कोई त्रुटि नहीं मिलती है। मेरा सवाल यह है कि इस मामले में वालग्रिंड के साथ क्या होता है? 32 या 64 बिट्स के लिए रन वाल्ग्रिंड के लिए कोई रास्ता है?

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define id_lenght 6000 
typedef unsigned char * ustring; 
typedef struct { 
    ustring ustr; 
    int height; 
    char id[id_lenght]; 
} node; 

int validation_read(void * ptr_var, size_t sizeof_datatype, int num, 
    FILE * ptr_file) { 
    if (fread(ptr_var, sizeof_datatype, num, ptr_file) <= 0) { 
     printf("Error reading file"); 
     return 1; 
    } 
return 0; 
} 

void node_read(FILE * node_ptr, node * n, int r) { 
    int i; 
    validation_read(n->id, sizeof(unsigned char), id_lenght, node_ptr); 
    validation_read(&(n->height), sizeof(int), 1, node_ptr); 
    validation_read(n->ustr, sizeof(unsigned char) * (r + 1), 1,node_ptr); 
} 

void node_init(node * n, int r) { 
    memset(n, 0, sizeof(node)); 
    n->ustr = malloc((r + 1) * sizeof(unsigned char)); 
    memset(n->ustr, 0, (r + 1)); 
    n->ustr[r] = 0; 
    n->height = -1; 
    memset(n->id,0,id_lenght+1); 
} 


void node_write(FILE * node_ptr, node * n, int r) { 
    int i; 
    char newid[id_lenght]; 
    memset(newid,0,id_lenght); 
    sprintf(newid,"%s",n->id); 
    fwrite(newid, sizeof(char), id_lenght+1, node_ptr); 
    fwrite(&(n->height), sizeof(int), 1, node_ptr); 
    fwrite(n->ustr, sizeof(unsigned char) * (r + 1), 1,node_ptr); 
} 


void node_destroy(node * n) { 
    free(n->ustr); 
    n->height = -1; 
} 

int main(){ 
    FILE * ptr = fopen("juantest","w+"); 
    int r = 64/8; 
    node in; 
    node_init(&in, r); 
    node_write(ptr, &in, r); 
    node_destroy(&in); 
    fclose(ptr); 
} 

संपादित लेकिन एक समस्या होता है जब मैं फ़ाइल पढ़ने का प्रयास। मैंने अपना उपरोक्त कोड संपादित किया। मुझे फ़ाइल पढ़ने में त्रुटि मिलती है त्रुटि पढ़ने वाली फ़ाइल

+0

आपका कोड पठनीय नहीं है, कृपया इसे प्रारूपित करें। और परिभाषा के अनुसार 'आकार (char) == 1'। –

+1

आपकी "फ़ाइल पढ़ने में त्रुटि" 3 बार दिखाई देने का मतलब यह होना चाहिए कि फ़ाइल में कुछ भी * लिखित * नहीं है, या आप फ़ाइल में लिख रहे हैं और तुरंत इसे पढ़ने का प्रयास करें। – usr2564301

+0

फ़ंक्शन में: node_read() और फ़ंक्शन में: node_write(): इनमें से प्रत्येक फ़ंक्शन में स्टैक पर एक चर होता है: 'i' जिसका उपयोग नहीं किया जाता है। सुझाव 1) उन दो चर हटा दें। 2) उन चेतावनियों को संकलित और ठीक करते समय सभी चेतावनियों को सक्षम करें (बाद में, संकलक सी भाषा को आपके से बहुत बेहतर जानता है या मैं करता हूं।) – user3629249

उत्तर

6

वालग्रिंड चिंता करने का अधिकार है। इस लाइन में

fwrite(newid, sizeof(char), id_lenght+1, node_ptr); 

आप अनुमति से 1 बाइट अधिक डेटा लिख ​​रहे हैं; एक से परे आपकी नई अस्थायी स्टैक स्ट्रिंग।

fwrite(newid, sizeof(char), id_length, node_ptr); 

चूंकि आप एक फाइल करने के लिए स्मृति सामग्री डंपिंग कर रहे हैं, तो आप स्ट्रिंग स्पष्ट करने के लिए सही हैं: तुम शायद वास्तव में (अधिकतम) बफर आकार इस्तेमाल किया लेखन के साथ एक स्ट्रिंग (समाप्त शून्य के लिए एक +1 के साथ) लेखन उलझन में sprintf का उपयोग करने से पहले स्मृति। आप कभी नहीं जानते कि ताजा आवंटित स्मृति के अंदर क्या है!
ध्यान दें कि यदि आप डेटा अखंडता के बारे में चिंतित हैं, तो इसके बजाय सुरक्षित संस्करण sprintf_s का उपयोग करना हमेशा बेहतर होता है, क्योंकि यह आपको इस बफर को चलाने से बचाएगा।

+1

हो सकती है, लेकिन मैं एक निश्चित लेंस एरे न्यूड – Juan

+0

@ जुआन लिखना चाहता हूं: उचित बिंदु (और मैं था यह सोचकर कि आप उस स्ट्रिंग को वापस कैसे पढ़ेंगे!)। डिस्क पर लिखने से पहले स्ट्रिंग को साफ़ करने के लिए मेरा उत्तर उलटा, और आपके लिए एक +1। लेकिन सुरक्षा के लिए '_s' कार्यों में देखें। इसके अलावा कृपया # परिभाषित करने के लिए ALL_CAPS का उपयोग करें - यह एक सम्मेलन है लेकिन एक सुंदर मजबूत है। – usr2564301

+0

मैं अपना प्रश्न संपादित करता हूं ... – Juan

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