Printf似乎在覆盖指针

时间:2014-12-11 23:42:58

标签: c pointers linked-list

在我第一次打印printf打印出副本之后,然后将它的哺乳动物指针改为giberish。因此,当它在第二个循环内打印时,第一个哺乳动物出来很好但是然后列表中的下一个丢失了。然后,每次退出该循环时,列表​​中的下一个副本都将丢失。

void print_list3() {
Duplicate *next=head3.duppointer;
int i,j;
for(i=0;i<list_length3;i++) {
    printf("%c %d %f %f\n",next->species,next->number_of,next->location.lat,next->location.lng);
    Mammal mam;
    mam=*next->mampointer;
    for(j=0;j<next->number_of;j++) {
        printf("   %f %f %s\n",mam.location.lat,mam.location.lng,mam.observer.id);
        if (mam.pointer!=NULL) {
            mam=*mam.pointer;
        }
    }
    if (next!=NULL) {
        next=next->duppointer;
    }
}

}

编辑:决定将我的所有代码放在这里,也许你们更容易找到这个bug。问题出在功能2上。

    #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "navigation.h"
#include "Mainheader.h"
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <math.h>

int list_length1=0;
int list_length2=0;
int list_length3=0;
Observer head1;
Mammal head2;
Duplicate head3;
/*
 * 
 */
int main(int argc, char** argv) {
    int choice=0;
    run_menu();
    scanf("%d",&choice);
    while(choice<1 || choice>4) {
        printf("Invalid choice\n");
        scanf("%d",&choice);
    }
    if(choice==1) {
        function1();
    }
    else if(choice==2) {
        function2();
    }
    else if(choice==3) {
        function3();
    }
    else if(choice==4) {
        printf("Exiting!");
    }
    return (EXIT_SUCCESS);
}

void run_menu() {
    printf("1 - Display cetacean Mammals          fn1\n"
           "2 - Display without duplicates        fn2\n"
           "3 - Display Pods without duplicates   fn3\n"
           "4 - Exit\n");
}

void function1(){
    int i=0;
    get_directories();
    Mammal *next;
    next=head2.pointer;
    for(i=0;i<list_length2;i++) {
        location_calculator(next);
        if (next!=NULL) {
            next=next->pointer;
        }
    }   
    print_reallist();
}
void function2(){
    int i=0;
    get_directories();
    Mammal *next;
    next=head2.pointer;
    for(i=0;i<list_length2;i++) {
        location_calculator(next);
        if (next!=NULL) {
            next=next->pointer;
        }
    }
    remove_duplicates();
    print_list3();
}
void function3(){

}
char get_directories() {
    char file1[256];
    char file2[256];
    char obsid[5];
    TD td;
    FILE *file_no1;
    FILE *file_no2;
    Observer* obs=malloc(sizeof(*obs));
    Mammal* mam=malloc(sizeof(*mam));
    //printf("Please Enter Observer File Path: ");
    //scanf("%s",&file1);
    strcpy(file1,"/ceri/homes1/j/jsc12/CS237/Assignment/cetaceans/data/observers_2.txt");
    file_no1=fopen(file1, "r");
    fscanf(file_no1,"%d%d%d%d%d%d",&td.day,&td.month,&td.year,&td.hour,&td.minute,&td.second);
    while(fscanf(file_no1,"%s%lf%lf",obs->id,&obs->location.lat,&obs->location.lng)==3) {
        obs->timedate=td;
        Observer *new;
        new=create_observer(obs->id,obs->location,obs->timedate);
        add_observer(new);
    }
    fclose(file_no1);
    //printf("Please Enter Sighting File Path: ");
    //scanf("%s",&file2);
    strcpy(file2,"/ceri/homes1/j/jsc12/CS237/Assignment/cetaceans/data/sightings_2.txt");
    file_no2=fopen(file2, "r");
    while(fscanf(file_no2,"%4s %c %lf%lf",&obsid,&mam->species,&mam->bearing,&mam->range)==4) {
        Observer* obs2=find_observer(obsid);
        mam->observer=*obs2;
        Mammal *new;
        new=create_mammal(mam->observer,mam->species,mam->bearing,mam->range);
        add_mammal(new);
    }
    fclose(file_no2);
}
Mammal* create_mammal (Observer obs,char spec,double bear,double ran){
    Mammal* b=malloc(sizeof *b);
    b->observer=obs;
    b->species=spec;
    b->bearing=bear;
    b->range=ran;
    b->pointer=NULL;

    return b;
}
void add_mammal (Mammal *n){
    n->pointer=head2.pointer;
    head2.pointer=n;
    list_length2++;
}
Duplicate* create_duplicate (Duplicate* d){
    Mammal mam;
    int i;
    location average;
    average.lat=0;
    average.lng=0;
    mam=*d->mampointer;
    Duplicate* b;
    b=malloc(sizeof *b);
    b->species=d->mampointer->species;
    b->number_of=d->number_of;
    for(i=0;i<d->number_of;i++) {
        average.lat+=mam.location.lat;
        average.lng+=mam.location.lng;
        if (mam.pointer!=NULL) {
            mam=*mam.pointer;
        }
    }
    average.lat/=d->number_of;
    average.lng/=d->number_of;
    b->location=average;
    b->mampointer=d->mampointer;
    b->duppointer=NULL;

    return b;
}
void add_duplicate (Duplicate *n){
    n->duppointer=head3.duppointer;
    head3.duppointer=n;
    list_length3++;
}
Observer* create_observer (char id[5],location locat,TD timdat){
    Observer* b=malloc(sizeof *b);
    strcpy(b->id,id);
    b->location=locat;
    b->timedate=timdat;
    b->pointer=NULL;
    return b;
}
void add_observer (Observer *n){
    n->pointer=head1.pointer;
    head1.pointer=n;
    list_length1++;
}
Observer* find_observer(char id[5]) {
    Observer *next=head1.pointer;
    int i=0;
    while(i<list_length1) {
        if(strcmp(id,next->id)==0) {
            return(next);
        }
        next=next->pointer;
        i++;
    }
}

void location_calculator(Mammal* m) {
    double obslat=m->observer.location.lat;
    double obslng=m->observer.location.lng;
    double rbear=(m->bearing*M_PI)/180;
    m->location.lat=obslat+(m->range*cos(rbear))/60;
    m->location.lng=obslng+(m->range*sin(rbear)/cos((obslat*M_PI)/180))/60;
}
void print_reallist() {
    Mammal *next=head2.pointer;
    int i;
    printf("|==========|==========|==========|==========|\n");
    printf("|%-10s|%-10s|%-10s|%-10s|\n","Longitude","Latitude","Species","Observer");
    printf("|==========|==========|==========|==========|\n");
    for(i=0;i<list_length2;i++) {
        if (next->species=='P') {
            printf("|%-10lf|%-10lf|%-10s|%-10s|\n",next->location.lat,next->location.lng,"Porpoise",next->observer.id);
            if (next!=NULL) {
                next=next->pointer;
            } 
        }
        else {
            printf("|%-10lf|%-10lf|%-10s|%-10s|\n",next->location.lat,next->location.lng,"Dolphin",next->observer.id);
            if (next!=NULL) {
                next=next->pointer;
            }
        }
    }
    printf("|==========|==========|==========|==========|\n");
}
void remove_duplicates() {
    int i,j;
    double distance;
    Mammal *next=head2.pointer;
    for(i=0;i<list_length2-1;i++) {
        Mammal *check=next->pointer;
        Duplicate d;
        d.mampointer=NULL;
        d.number_of=0;
        for(j=0;j<(list_length2-i)-1;j++) {
            distance=great_circle(next->location, check->location);
            if(distance<=0.02 && next->species==check->species) {
                Mammal a=*next;
                Mammal b=*check;
                a.pointer=d.mampointer;
                d.mampointer=&a;
                b.pointer=d.mampointer;
                d.mampointer=&b;
                d.number_of++;
                d.number_of++;
            }
            printf("%f\n",distance);
            if (check!=NULL) {
                check=check->pointer;
            } 
        }
        if(d.mampointer!=NULL) {
            add_duplicate(create_duplicate(&d));
        }
        if (next!=NULL) {
            next=next->pointer;
        } 
    }
}
void print_list3() {
    Duplicate *next=head3.duppointer;
    int i,j;
    for(i=0;i<list_length3;i++) {
        printf("%c %d %f %f\n",next->species,next->number_of,next->location.lat,next->location.lng);
        Mammal mam;
        mam=*next->mampointer;
        for(j=0;j<next->number_of;j++) {
            printf("   %f %f %s\n",mam.location.lat,mam.location.lng,mam.observer.id);
            if (mam.pointer!=NULL) {
                mam=*mam.pointer;
            }
        }
        if (next!=NULL) {
            next=next->duppointer;
        }
    }
}

1 个答案:

答案 0 :(得分:1)

第一眼就有很多问题。

这是C,但最好避免使用名称&#39; new&#39;。标识符位置&#39;也是结构名称和变量名称。函数char get_directories()和Observer * find_observer()并不总是返回。

有五个malloc()但没有free()调用。

我担心这样的函数声明不能​​保证字符串大小,传递一个简单的指针:

Observer * create_observer ( char id[5], ..

未检查fscanf的返回值。预期6但实际上返回1,因为没有提供适当的格式。也许尝试&#34;%2d%2d%2d%2d%2d%2d&#34;!

fscanf(file_no1,"%d%d%d%d%d%d",&td.day,&td.month,&td.year,&td.hour,&td.minute,&td.second);

观察者线也有同样的问题。 fscanf应该如何知道字符串和/或double的结尾?试试例如&#34;%4s%lf%lf&#34;!

while(fscanf(file_no1,"%s%lf%lf",obs->id,&obs->location.lat,&obs->location.lng)==3) {

此时未正确扫描String obsid(删除地址运算符&amp;):

while(fscanf(file_no2,"%4s %c %lf%lf",&obsid,&mam->species,&mam->bearing,&mam->range)==4) {

如果找不到obsid,函数find_observer()将正确返回NULL。在这种情况下不应使用指针,因此请先检查obs2:

Observer* obs2=find_observer(obsid);
mam->observer=*obs2;

您能否提供带有示例输入的代码部分来重现问题并解决问题?我甚至不得不进行逆向工程以获得以下结构进行编译:

struct Loc { double lat; double lng; };
struct TD { int year; int month; int day;  int hour; int minute; int second; };
struct Observer { char id[1024]; Loc location; TD timedate; Observer * pointer; };
struct Mammal { char species; double bearing; double range; Observer observer; Mammal * pointer; Loc location; };
struct Duplicate { Mammal * mampointer; int number_of; char species; Loc location; Duplicate * duppointer; };

还缺少great_circle(Loc,Loc)功能。替换为平面距离计算而不是假设的球形:

double great_circle( Loc p0, Loc p1 ) { return pow( ( p0.lat - p1.lat ), 2.0 ) + pow( ( p0.lng - p1.lng ), 2.0 ); }

在没有尝试重复的情况下,在修复上述错误后,它可以正常运行。