سؤال

ولدي ملف نصي المفصول أنني تحليل. يحتوي العمود الأول سلاسل من chrX الشكل، حيث يدل X مجموعة من السلاسل، على سبيل المثال، "1"، "2"، ...، "X"، "Y".

وهذه هي كل تخزينها في char* دعا chromosome، كما يتم تحليل الملف.

ويتم فرز ملف نصي على العمود الأول lexicographically، أي، وسوف يكون لديك عدد الصفوف بدءا من "chr1"، ثم "chr2"، وما إلى ذلك.

وفي كل دخول "chrX"، ولست بحاجة لفتح ملف آخر مقترن هذا الموضوع:

FILE *merbaseIn;

// loop through rows...

if (chromosome == NULL)                                                                                                                                                   
    openSourceFile(&chromosome, fieldArray[i], &merbaseIn, GENPATHIN);                                                                                                      
else {                                                                                                                                                                    
    if (strcmp(chromosome, fieldArray[i]) != 0) { // new chromosome                                                                                                   
        fclose(merbaseIn); // close old chromosome FILE ptr                                                                                                                                                                                                                                    
        free(chromosome); // free old chromosome ptr                                                                                                                          
        openSourceFile(&chromosome, fieldArray[i], &merbaseIn, GENPATHIN); // set up new chromosome FILE ptr                                                                  
    }                                                                                                                                                                       
}  
// parse row

ولدي openSourceFile وظيفة التي تم تعريفها على النحو التالي:

void openSourceFile (char** chrome, const char* field, FILE** filePtr, const char *path) {
    char filename[100];                                                                                                                                                           
    *chrome = (char *) malloc ((size_t) strlen(field));
    if (*chrome == NULL) {                                                                                                                                                        
        fprintf(stderr, "ERROR: Cannot allocate memory for chromosome name!");                                                                                                      
        exit(EXIT_FAILURE);                                                                                                                                                         
    }                                                                                                                                                                             

    strcpy(*chrome, field);                                                                                                                                                       
    sprintf(filename,"%s%s.fa", path, field);                                                                                                                                     

    *filePtr = fopen(filename, "r");                                                                                                                                              
    if (*filePtr == NULL) {                                                                                                                                                       
        fprintf(stderr, "ERROR: Could not open fasta source file %s\n", filename);                                                                                                  
        exit(EXIT_FAILURE);                                                                                                                                                         
    }                                                                                                                                                                             
}      

والمشكلة هي أن طلبي إنهاء مع خطأ الإنقسام الانتقال من الكروموسوم الأول إلى الثاني (من chr1 إلى chr2) في السطر التالي، حيث أن أغلق أول ملف كروموسوم التي فتحت:

fclose(merbaseIn);

وأنا أعلم أنني لست يمر fclose مؤشر NULL، لأن حتى صدع الإنقسام، وأنا قراءة البيانات من هذا الملف. حتى أستطيع أن التفاف ذلك في مشروطة وأنا لا يزال الحصول على خطأ:

if (merbaseIn != NULL) {
    fclose(merbaseIn);
}

وعلاوة على ذلك، وأنا أعلم أعمال openSourceFile (على الأقل بالنسبة chr1، عند إعداد مؤشر الملف الأول من FILE*) لطلبي يوزع صفوف chr1 ويقرأ البيانات من ملف مصدر FILE* بشكل صحيح.

وماذا عن هذه الدعوة fclose الذي يسبب خطأ الإنقسام أن يحدث؟

هل كانت مفيدة؟

المحلول

valgrind --db-attach=yes --leak-check=yes --tool=memcheck --num-callers=16 --leak-resolution=high ./yourprogram args

ومن المرجح جدا هو سبب segfault من قبل تلف الذاكرة على كومة، وليس أي شيء يؤثر على السكان المحليين. Valgrind سوف تظهر لك على الفور أول وصول الخطأ التي تقوم بها.

وتحرير: تم إيقاف الخيار --db-attach إلى valgrind منذ الإفراج 3.10.0 في عام 2014. ويشير إطلاق الدولة:

The built-in GDB server capabilities are superior and should be used
instead. Learn more here:

http://valgrind.org /docs/manual/manual-core-adv.html#manual-core-adv.gdbserver

نصائح أخرى

وخطأ واحد أنا لاحظت هو هذا السطر:

 *chrome = (char *) malloc ((size_t) strlen(field));

والتي ينبغي أن تكون:

 *chrome = (char *) malloc ((size_t) strlen(field)+1);

وذلك لأن سلسلة لديها إغلاق 0 في نهاية التي لديك أيضا لإفساح المجال ل

وأفضل تخمين هو أن أي جزء آخر من التعليمات البرمجية هي الذاكرة المفسدة من خلال تجاوز سعة المخزن المؤقت أو خلل مماثل.

وعلى الرغم من المرجح أن يكون سبب، لديك حالة تجاوز المحتملة في مجموعة اسم الملف الخاص بك عندما يتجاوز اسم الملف الكامل 100 حرف.

وأود أن أقترح استخدام مصحح لمراقبة التغييرات في الموقع الذاكرة المستخدمة من قبل متغير merbaseIn.

عام المؤشر مشكلة

وC هي لغة عظيمة لكنها لا تتطلب منك لا هزم الذاكرة الخاصة بك. إلى جانب مشكلة لوحظ سابقا حيث malloc هو 1 بايت القصير، قد يكون لديك مشاكل مؤشر أخرى.

وأود أن أقترح باستخدام المصحح ذاكرة . في الماضي، كان الكهربائية سياج شعبية نوعا ما ولكن في هذه الأيام I <لأ href = "HTTP: //en.wikipedia.org/wiki/Valgrind "يختلط =" نوفولو noreferrer "> سماع المزيد عن valgrind . هناك الكثير من الخيارات الأخرى.

وبالإضافة إلى الخطأ وجدت من قبل اللاعب Reinier ، وأظن أن:

free(chromosome);

يجب أن يتبعها:

chromosome = NULL;

ومن أجل منع استخدام محتمل لقيمة لم تعد صالحة.

لماذا هذا FILE ** filePtr إلا إذا كان هذا FILE * filePtr سيكون كافيا؟ مجرد التفكير ...

وvalgrind مع memcheck هو بالتأكيد الأداة المناسبة لاكتشاف سبب خطأ تجزئة. لاستخدام المصحح مع valgrind، لاحظ أن الخيار --db-attach إلى valgrind تم إهمال منذ صدر Valgrind 3.10.0 في عام 2014. ويشير إطلاق الدولة:

The built-in GDB server capabilities are superior and should be used
instead. Learn more here:

http://valgrind.org /docs/manual/manual-core-adv.html#manual-core-adv.gdbserver

ومراجعة كل مكان استخدمته على "malloc" ثم نرى ما اذا كان ارتكب خطأ.

وعلى سبيل المثال، كنت في وضع خطوط قراءة من ملف إلى شار **، لكنني غير صحيح malloced على النحو التالي:

my_list = malloc(sizeof(char) * num_lines_found_in_file);

وعندما كان ينبغي أن يكون:

my_list = malloc(sizeof(char*)* num_lines_found_in_file);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top