Page 1 of 1
απορία σε C
Posted: Sat Apr 17, 2010 2:46 pm
by black7ack
Παιδιά θα μπορούσε κάποιος να με βοηθήσει να βρω το λόγο που πετάει seg fault στο παρακάτω κώδικα?
Eίναι ένα πολύ απλό πρόγραμμα που διαβάζει ένα txt αρχείο το περνάει σε έναν pointer και στη συνέχεια τον κάνει save σε ένα άλλο txt αρχείο.
Το πρόβλημα το έχω εντωπίσει στην mapload και συγκεκριμένα όταν παει να φορτώσει τον πίνακα στον array.
Eίμαι 99% σίγουρος ότι δεν βγαίνει έξω από τα άκρα.
- Spoiler: εμφάνιση/απόκρυψη
[code]#include <stdio.h>
#include <stdlib.h>
int countlines=0, max=0;
main()
{
FILE *map;
int i=0,counter=0;
char *storE=NULL;
if ((map = fopen("px1", "r"))==NULL){
printf("Cannot open map file!\n Press X to exit and anything else to repeat with a new path for the map");
} else {
counts(map, &countlines, &max);
printf("grammes------>%d\nstilles------> %d\n", countlines,max);
getchar();
storE=malloc((max)*(countlines)*sizeof(char));
if (storE==NULL){
printf("malloc function failed");
exit(0);
};
mapload("px1", &storE,max , countlines);
mapsave("pr2.c", &storE,max , countlines);
};
return 0;
};
counts(FILE *map,int *countlines,int *max){
char tmp1;
int countcolumns=0;
while (fscanf(map, "%c", &tmp1)!=EOF){
if (tmp1!='\n'){
countcolumns+=1;
printf("%c %d\n", tmp1, countcolumns);
}
else if (tmp1=='\n'){
countcolumns+=1;
*countlines+=1;
printf("%c %d %d\n", tmp1, countcolumns, *countlines);
if (countcolumns>*max)
*max=countcolumns;
countcolumns=0;
};
};
printf("%d %d\n", *countlines,*max);
rewind(map);
clearerr(map);
};
int mapload(char *filename, char *storE,int max,int countlines){
FILE *map;
int i=0,count=0, counter=0, cHECK=0, mpourda=0;
char tmp='0',check='r';
if ((map = fopen(filename, "r"))==NULL){
printf("Cannot open map file!\n Press X to exit and anything else to repeat with a new path for the map");
scanf("%c", &check);
} else {
/*while ((fscanf(map,"%c", &tmp)==1)){
switch (tmp)
{
case '\n' : if(counter!=(max-1)){
for(;counter<max-1;counter++){
printf("(%d,%d)",i,(counter));
storE[loc(i,counter)]='*';
printf("---> %c\n", storE[loc(i,counter)]);
};
storE[loc(i,counter)]='\n';
printf("(%d,%d)",i,(counter));
printf("---> %c\n", storE[loc(i,counter)]);
} else {
storE[loc(i,counter)]='\n';
printf("(%d,%d)",i,(counter));
printf("---> %c\n", storE[loc(i,counter)]);
};
cHECK=0;
i+=1;
counter=0;
break;
case '*' : if (!cHECK)
cHECK=1;
storE[loc(i,counter)]='*';
printf("(%d,%d)",i,(counter));
printf("---> %c\n", storE[loc(i,counter)]);
counter+=1;
break;
default : if (!cHECK){
storE[loc(i,counter)]='*';
printf("(%d,%d)",i,(counter));
printf("---> %c\n", storE[loc(i,counter)]);
} else {
storE[loc(i,counter)]=tmp;
printf("(%d,%d)",i,(counter));
printf("---> %c\n", storE[loc(i,counter)]);
};
counter+=1;
break;
};*/
for(counter=0;fscanf(map,"%c", &tmp)!=EOF;counter++){
storE[counter]=tmp;
printf("(%d,%c)",i,(counter));
printf("---> %c\n", storE[counter]);
};
};
/*for(i-=1;counter<(max-1);counter++){
*(storE+loc(i,counter))='*';
printf("(%d,%d)",i,(counter));
printf("---> %c\n", storE[loc(i,counter)]);
};
*(storE+loc(i,counter))='\n';
printf("(%d,%d)",i,(counter));
printf("---> %c\n", storE[loc(i,counter)]);
printf("SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS\n");*/
/*for(i=0;i<(countlines);i++){
for(counter=0;counter<(max);counter++){
printf("%c", storE[loc(i,counter)]);
};
};*/
return 0;
};
mapsave(char *filename, char *storE,int max, int countlines){
FILE *map;
int i=0, counter=0;
if ((map=fopen(filename , "w"))==NULL){
printf(" Could not write map file!\n");
exit(0);
} else {
for(i=0;i<(countlines);i++)
for(counter=0;counter<(max);counter++){
fprintf(map, "%c", storE[loc(i,counter)]);
printf("%c", storE[loc(i,counter)]);
};
};
rewind(map);
fclose(map);
};
int loc(int i, int j){
return (i*max+j);
}
[/code]
Re: απορία σε C
Posted: Sat Apr 17, 2010 3:03 pm
by AmmarkoV
hm είναι αρκετά μεγάλο ..
μερικές 1st scan παρατηρήσεις
counts(FILE *map,int *countlines,int *max){ δεν έχεις βάλει τύπο ( void πχ )
mapsave(char *filename, char *storE,int max, int countlines επίσης
γιατί γράφεις παντού } ; το ; είναι redundant..
Θα το κοιτάξω πιο αναλυτικά πιο μετά ..
Αν θές δοκίμασε να το τρέξεις με Valgrind σε Debug Compilatιon
Επίσης τι σύστημα / compiler κτλ το τρέχεις ?
Re: απορία σε C
Posted: Sat Apr 17, 2010 3:11 pm
by black7ack
δεν ήμουνα σίγουρος για το αν είναι ή όχι απαραίτητο το }; και είπα καλύτερα άχρηστο και μέσα παρά απαραίτητο και έξω , εύχαριστώ πάντως από εδώ και πέρα θα ξέρω.
κατα τα άλλα το έτρεξα με valgrind αλλά δεν έβγαλα άκρη πιθανώς και λόγω απειρίας αν θμπορείς ρίξε μια μα
ubuntu 9.10 με τον gcc compiler που ερχεται πακέτο.
Re: απορία σε C
Posted: Sat Apr 17, 2010 3:19 pm
by AmmarkoV
επίσης αντίστοιχα το main() στην αρχή θα έπρεπε να είναι int main()
από εκεί και εμπρός προφανώς παίζει πολύ μεγάλο ρόλο και το τι έχει μέσα το αρχειάκι px1 που πας να ανοίξεις γιατί δεν έχεις βάλει έλεγχο για το πόσο διαβάζεις απο εκεί οπότε μπορεί άνετα να κάνει buffer overflow στο malloc που κάνεις
με το Valgrind τρέξε :
valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes YOUREXECUTABLEPATHHERE
και postαρε τα αποτελέσματα
Re: απορία σε C
Posted: Sat Apr 17, 2010 3:26 pm
by black7ack
αφου πρώτα τρέχει το counts που μετράει το μήκος κάθε γραμμής του txt αρχείου καθώς και πόσες γραμμές έχει και μετά κάνει μία malloc για maxμηκοςγραμμης*πλήθοςγραμμων*sizeof(char) πως είναι δυνατόν να βγει απ'έξω?
ορίστε πάντως τα αποτελέσματα του valgrind
- Spoiler: εμφάνιση/απόκρυψη
==17990== Jump to the invalid address stated on the next line
==17990== at 0x2D2A0A2A: ???
==17990== Address 0x2d2a0a2a is not stack'd, malloc'd or (recently) free'd
==17990==
==17990==
==17990== Process terminating with default action of signal 11 (SIGSEGV)
==17990== Access not within mapped region at address 0x2D2A0A2A
==17990== at 0x2D2A0A2A: ???
==17990== If you believe this happened as a result of a stack
==17990== overflow in your program's main thread (unlikely but
==17990== possible), you can try to increase the size of the
==17990== main thread stack using the --main-stacksize= flag.
==17990== The main thread stack size used in this run was 8388608.
==17990==
==17990== FILE DESCRIPTORS: 5 open at exit.
==17990== Open file descriptor 4: px1
==17990== at 0x40FD933: __open_nocancel (in /lib/tls/i686/cmov/libc-2.10.1.so)
==17990== by 0x40A8B17: _IO_file_fopen@@GLIBC_2.1 (fileops.c:335)
==17990== by 0x409CE4C: __fopen_internal (iofopen.c:93)
==17990== by 0x409CEAB: fopen@@GLIBC_2.1 (iofopen.c:107)
==17990== by 0x8048907: mapload (in /home/giannis/a.out)
==17990== by 0x804879B: main (in /home/giannis/a.out)
==17990==
==17990== Open file descriptor 3: px1
==17990== at 0x40FD933: __open_nocancel (in /lib/tls/i686/cmov/libc-2.10.1.so)
==17990== by 0x40A8B17: _IO_file_fopen@@GLIBC_2.1 (fileops.c:335)
==17990== by 0x409CE4C: __fopen_internal (iofopen.c:93)
==17990== by 0x409CEAB: fopen@@GLIBC_2.1 (iofopen.c:107)
==17990== by 0x80486DA: main (in /home/giannis/a.out)
==17990==
==17990== Open file descriptor 2: /dev/pts/3
==17990== <inherited from parent>
==17990==
==17990== Open file descriptor 1: /dev/pts/3
==17990== <inherited from parent>
==17990==
==17990== Open file descriptor 0: /dev/pts/3
==17990== <inherited from parent>
==17990==
==17990==
==17990== HEAP SUMMARY:
==17990== in use at exit: 779 bytes in 3 blocks
==17990== total heap usage: 4 allocs, 1 frees, 1,131 bytes allocated
==17990==
==17990== 75 bytes in 1 blocks are definitely lost in loss record 1 of 3
==17990== at 0x4024C1C: malloc (vg_replace_malloc.c:195)
==17990== by 0x804874F: main (in /home/giannis/a.out)
==17990==
==17990== 352 bytes in 1 blocks are still reachable in loss record 2 of 3
==17990== at 0x4024C1C: malloc (vg_replace_malloc.c:195)
==17990== by 0x409CDDE: __fopen_internal (iofopen.c:76)
==17990== by 0x409CEAB: fopen@@GLIBC_2.1 (iofopen.c:107)
==17990== by 0x80486DA: main (in /home/giannis/a.out)
==17990==
==17990== 352 bytes in 1 blocks are still reachable in loss record 3 of 3
==17990== at 0x4024C1C: malloc (vg_replace_malloc.c:195)
==17990== by 0x409CDDE: __fopen_internal (iofopen.c:76)
==17990== by 0x409CEAB: fopen@@GLIBC_2.1 (iofopen.c:107)
==17990== by 0x8048907: mapload (in /home/giannis/a.out)
==17990== by 0x804879B: main (in /home/giannis/a.out)
==17990==
==17990== LEAK SUMMARY:
==17990== definitely lost: 75 bytes in 1 blocks
==17990== indirectly lost: 0 bytes in 0 blocks
==17990== possibly lost: 0 bytes in 0 blocks
==17990== still reachable: 704 bytes in 2 blocks
==17990== suppressed: 0 bytes in 0 blocks
==17990==
==17990== For counts of detected and suppressed errors, rerun with: -v
==17990== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 11 from 6)
οριστε και τα περιεχόμενα του txt με το οποίο πειραματίζομαι
- Spoiler: εμφάνιση/απόκρυψη
**************
*--2--------@*
*-------2----*
*-2-------#--*
*sakfjhalsfkh*
Re: απορία σε C
Posted: Sat Apr 17, 2010 3:31 pm
by AmmarkoV
Δεν κάνεις fclose το map stream πριν καλέσεις mapload !
Και δεν ελέγχεις αν είναι ok το stream που άνοιξες..!
fp = fopen(filename,"r");
if (fp == NULL) { fprintf(stderr,"Den anoigei to file..!"); return 0; }
fclose(fp);
Re: απορία σε C
Posted: Sat Apr 17, 2010 3:38 pm
by black7ack
βασικά έλεγχο κάνω είναι το πρώτο πράγμα που κάνω μέσα στη main().
Πάντως δεν το έκλεινα πριν το ξανανοίξω μέσα στην mapload. Έβαλα λοιπόν
rewind(map);
fclose(map);
το πρόβλημα όμως δεν λύθηκε.
- Spoiler: εμφάνιση/απόκρυψη
==22171== Jump to the invalid address stated on the next line
==22171== at 0x2D2A0A2A: ???
==22171== Address 0x2d2a0a2a is not stack'd, malloc'd or (recently) free'd
==22171==
==22171==
==22171== Process terminating with default action of signal 11 (SIGSEGV)
==22171== Access not within mapped region at address 0x2D2A0A2A
==22171== at 0x2D2A0A2A: ???
==22171== If you believe this happened as a result of a stack
==22171== overflow in your program's main thread (unlikely but
==22171== possible), you can try to increase the size of the
==22171== main thread stack using the --main-stacksize= flag.
==22171== The main thread stack size used in this run was 8388608.
==22171==
==22171== FILE DESCRIPTORS: 4 open at exit.
==22171== Open file descriptor 3: px1
==22171== at 0x40FD933: __open_nocancel (in /lib/tls/i686/cmov/libc-2.10.1.so)
==22171== by 0x40A8B17: _IO_file_fopen@@GLIBC_2.1 (fileops.c:335)
==22171== by 0x409CE4C: __fopen_internal (iofopen.c:93)
==22171== by 0x409CEAB: fopen@@GLIBC_2.1 (iofopen.c:107)
==22171== by 0x804891F: mapload (in /home/giannis/a.out)
==22171== by 0x80487B3: main (in /home/giannis/a.out)
==22171==
==22171== Open file descriptor 2: /dev/pts/3
==22171== <inherited from parent>
==22171==
==22171== Open file descriptor 1: /dev/pts/3
==22171== <inherited from parent>
==22171==
==22171== Open file descriptor 0: /dev/pts/3
==22171== <inherited from parent>
==22171==
==22171==
==22171== HEAP SUMMARY:
==22171== in use at exit: 427 bytes in 2 blocks
==22171== total heap usage: 4 allocs, 2 frees, 1,131 bytes allocated
==22171==
==22171== 75 bytes in 1 blocks are definitely lost in loss record 1 of 2
==22171== at 0x4024C1C: malloc (vg_replace_malloc.c:195)
==22171== by 0x804874F: main (in /home/giannis/a.out)
==22171==
==22171== 352 bytes in 1 blocks are still reachable in loss record 2 of 2
==22171== at 0x4024C1C: malloc (vg_replace_malloc.c:195)
==22171== by 0x409CDDE: __fopen_internal (iofopen.c:76)
==22171== by 0x409CEAB: fopen@@GLIBC_2.1 (iofopen.c:107)
==22171== by 0x804891F: mapload (in /home/giannis/a.out)
==22171== by 0x80487B3: main (in /home/giannis/a.out)
==22171==
==22171== LEAK SUMMARY:
==22171== definitely lost: 75 bytes in 1 blocks
==22171== indirectly lost: 0 bytes in 0 blocks
==22171== possibly lost: 0 bytes in 0 blocks
==22171== still reachable: 352 bytes in 1 blocks
==22171== suppressed: 0 bytes in 0 blocks
==22171==
==22171== For counts of detected and suppressed errors, rerun with: -v
==22171== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 11 from 6)
ορίστε και ο ανανεομένος κώδικας.
- Spoiler: εμφάνιση/απόκρυψη
[code]#include <stdio.h>
#include <stdlib.h>
int countlines=0, max=0;
int main()
{
FILE *map;
int i=0,counter=0;
char *storE=NULL;
if ((map = fopen("px1", "r"))==NULL){
printf("Cannot open map file!\n Press X to exit and anything else to repeat with a new path for the map");
} else {
counts(map, &countlines, &max);
printf("grammes------>%d\nstilles------> %d\n", countlines,max);
getchar();
storE=malloc((max)*(countlines)*sizeof(char));
if (storE==NULL){
printf("malloc function failed");
exit(0);
};
rewind(map);
fclose(map);
mapload("px1", &storE,max , countlines);
mapsave("pr2.c", &storE,max , countlines);
};
return 0;
};
int counts(FILE *map,int *countlines,int *max){
char tmp1;
int countcolumns=0;
while (fscanf(map, "%c", &tmp1)!=EOF){
if (tmp1!='\n'){
countcolumns+=1;
printf("%c %d\n", tmp1, countcolumns);
}
else if (tmp1=='\n'){
countcolumns+=1;
*countlines+=1;
printf("%c %d %d\n", tmp1, countcolumns, *countlines);
if (countcolumns>*max)
*max=countcolumns;
countcolumns=0;
};
};
printf("%d %d\n", *countlines,*max);
rewind(map);
clearerr(map);
return 0;
};
int mapload(char *filename, char *storE,int max,int countlines){
FILE *map;
int i=0,count=0, counter=0, cHECK=0, mpourda=0;
char tmp='0',check='r';
if ((map = fopen(filename, "r"))==NULL){
printf("Cannot open map file!\n Press X to exit and anything else to repeat with a new path for the map");
scanf("%c", &check);
} else {
/*while ((fscanf(map,"%c", &tmp)==1)){
switch (tmp)
{
case '\n' : if(counter!=(max-1)){
for(;counter<max-1;counter++){
printf("(%d,%d)",i,(counter));
storE[loc(i,counter)]='*';
printf("---> %c\n", storE[loc(i,counter)]);
};
storE[loc(i,counter)]='\n';
printf("(%d,%d)",i,(counter));
printf("---> %c\n", storE[loc(i,counter)]);
} else {
storE[loc(i,counter)]='\n';
printf("(%d,%d)",i,(counter));
printf("---> %c\n", storE[loc(i,counter)]);
};
cHECK=0;
i+=1;
counter=0;
break;
case '*' : if (!cHECK)
cHECK=1;
storE[loc(i,counter)]='*';
printf("(%d,%d)",i,(counter));
printf("---> %c\n", storE[loc(i,counter)]);
counter+=1;
break;
default : if (!cHECK){
storE[loc(i,counter)]='*';
printf("(%d,%d)",i,(counter));
printf("---> %c\n", storE[loc(i,counter)]);
} else {
storE[loc(i,counter)]=tmp;
printf("(%d,%d)",i,(counter));
printf("---> %c\n", storE[loc(i,counter)]);
};
counter+=1;
break;
};*/
for(counter=0;fscanf(map,"%c", &tmp)!=EOF;counter++){
storE[counter]=tmp;
printf("(%d,%c)",i,(counter));
printf("---> %c\n", storE[counter]);
};
};
/*for(i-=1;counter<(max-1);counter++){
*(storE+loc(i,counter))='*';
printf("(%d,%d)",i,(counter));
printf("---> %c\n", storE[loc(i,counter)]);
};
*(storE+loc(i,counter))='\n';
printf("(%d,%d)",i,(counter));
printf("---> %c\n", storE[loc(i,counter)]);
printf("SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS\n");*/
/*for(i=0;i<(countlines);i++){
for(counter=0;counter<(max);counter++){
printf("%c", storE[loc(i,counter)]);
};
};*/
return 0;
};
int mapsave(char *filename, char *storE,int max, int countlines){
FILE *map;
int i=0, counter=0;
if ((map=fopen(filename , "w"))==NULL){
printf(" Could not write map file!\n");
exit(0);
} else {
for(i=0;i<(countlines);i++)
for(counter=0;counter<(max);counter++){
fprintf(map, "%c", storE[loc(i,counter)]);
printf("%c", storE[loc(i,counter)]);
};
};
rewind(map);
fclose(map);
return 0;
};
int loc(int i, int j){
return (i*max+j);
}
[/code]
Re: απορία σε C
Posted: Sat Apr 17, 2010 3:43 pm
by dexter
ρε άλλαξε την main βάλε int..

Re: απορία σε C
Posted: Sat Apr 17, 2010 3:45 pm
by black7ack
ρε εχω αρχίσει και τα παίζω θα ορκιζόμουνα οτι το είχα ήδη κάνει...
Re: απορία σε C
Posted: Sat Apr 17, 2010 3:47 pm
by dexter
το σχόλιο στην γραμμή /*for(i-=1;counter<(max-1);counter++){
που το κλείνεις?
Re: απορία σε C
Posted: Sat Apr 17, 2010 3:49 pm
by black7ack
ακριβώς πριν την return 0; η c από όσο ξέρω δεν υποστηρίζει φωλιασμένα σχόλια οπότε μην μπερδεύεσαι με τα ποιο μεσα */
Re: απορία σε C
Posted: Sat Apr 17, 2010 3:49 pm
by AmmarkoV
Κοίτα ανοίγεις ένα fopen και μετά καλείς την mapload που ξανακάνει fopen στο ήδη ανοιχτό stream με αποτέλεσμα αφενός δεύτερη fopen να επιστρέφει null pointer και μετά να προσπαθείς εσύ να διαβάσεις από null pointer..!
Re: απορία σε C
Posted: Sat Apr 17, 2010 3:57 pm
by dexter
black7ack wrote:ακριβώς πριν την return 0; η c από όσο ξέρω δεν υποστηρίζει φωλιασμένα σχόλια οπότε μην μπερδεύεσαι με τα ποιο μεσα */
σύμφωνα με αυτό το βιβλίο
http://www.amazon.com/C-Pocket-Referenc ... 985&sr=1-1
υποστηρίζει..
οπότε κάνε όλα τα σχόλια //
για να μην μπερδεύεσαι..
Re: απορία σε C
Posted: Sat Apr 17, 2010 4:00 pm
by AmmarkoV
Υποτίθεται οτι το /* */ είναι ο σωστός τρόπος για να βάζεις comments σε παραδοσιακή C τα // είναι C++ style..!
Re: απορία σε C
Posted: Sat Apr 17, 2010 4:57 pm
by black7ack
kosko θα σου προτεινα να δοκιμασεις αυτο που λες για τα σχόλια για να δεις και μόνο σου ότι δεν γίνεται.
AmmarkoV όντως έχεις μεγάλο δίκιο σε αυτό που λες, αλλά κατ' αρχάς είχα βάλει να ελέγχει για null pointer μέσα στην mapload όταν άνοιγε το αρχείο
και ακόμα και αφού έβαλα να το κλείνει πριν μπει στη mapload το πρόβλημα δεν διορθώθηκε.
----------
update αλλάζοντα την συνθήκη ελεγχου στο for loop που είναι υπεύθυνο για να φορτώνει τα στοιχεία του txt στον array
από
Code: Select all
for(counter=0;fscanf(map,"%c", &tmp)!=EOF;counter++){
σε
Code: Select all
for(counter=0;(fscanf(map,"%c", &tmp)!=EOF && counter<Ν);counter++)
παρατήρησα ότι για Ν<28 το πρόγραμμα δουλεύει και τερματίζει κανονικά xωρίς segfault αλλά για Ν>=29 πετάει segfault.
Ελπίζω να βοήθησα.
Re: απορία σε C
Posted: Sat Apr 17, 2010 7:03 pm
by AmmarkoV
δοκίμασε storE=malloc((max)*(countlines+1)*sizeof(char));
+1 στο countlines , δεν έχω προλάβει να το κοιτάξω αλλά λογικά θα φτιάξει.. (Voodoo programming)
Re: απορία σε C
Posted: Sat Apr 17, 2010 9:29 pm
by black7ack
το έχω δοκιμάσει ήδη ακόμα οφείλω να πω πως δεν πρέπει να είναι το μέγεθος του πίνακα γιατί δοκίμασα να δω αν μπορώ να τον αρχικοποιήσω με ένα for loop βάζοντας παντού '0' και τρέχει κανονικά χωρίς την mapload
--------
παιδιά ευχαριστώ για τον κόπο σας. Την βρήκα τη μλκια αντί να περάσω τον δείκτη που έπαιρνα από την malloc στην συνάρτηση πέρναγα τη διέυθυνση του δείκτη ('οτι να ναι!!!)
Ευχαριστώ πάντως η κουβέντα ήταν άκρως επικοδομητική και πιστεύω πως χωρίς αυτή δεν πρόκειται να το έβρισκα πόσο μάλλον τα άλλα λάθη.
Σόρρυ για τα greeklish mod ήταν από βιασύνη. Κόσκο σου χρωστάω μία μπυρίτσα κέρασμα.