2017-02-13 52 views
0

这个作业的点是由含有城市状态​​,接着由包含纬度和经度坐标两行的文件在一个要读取行。然后我们需要动态分配结构,就像下面写的那样来存储这些坐标。最后,我们将地标导出为Google地球使用的KML格式。ReAlloc如果包含结构的数组动态调整char指针

在这一点上,我可以正确地从我的结构写的KML。然而,在我的grow_whole函数中花了几个脏循环(见下文)。这个问题是我在后来释放所有分配的指针时。 (相信我,它存在虐待按顺序粘贴它)。我很确定问题是堆腐败。但是,我一直在这方面工作太久,我觉得它可能会更简单。

的文件格式。 (有像的这些150)

city, state 
40 30 N 
40 20 W 

Wholesome_t只是将容纳在界标结构的量以及指针到第一地标信息的容器。 Landmark_t保存指向chars的指针,这些chars分配的空间量足以包含他们解析的城市名称等。

struct landmark_t { 
char *city; 
char *state; 
char *country; 
float longitude; 
float latitude; 
}; 

struct wholesome_t { 
struct landmark_t *landmarks; 
int landcount; 
int landmax; 
}; 

下面是处理读取行并将它们发送到正确的解析器的代码块。

最初有益健康是malloc分配和地标指针被设置为NULL。 然后我们为2个具有里程碑意义的结构指定malloc空间,并开始下面的while循环。

struct landmark_t *land = NULL; 
int coorflag = 0; 
int flagcount = 0; 
//Parse lines 
while(fgets(buf, LEN, in)){ 
    //Does that thing where we realloc 
    if(whole->landcount == whole->landmax){ 
     grow_whole(whole); 
    } 

    //remove trailing newline 
    buf[strcspn(buf, "\n")] = 0; 

    if(!coorflag){//Check to see if we are on a flag or coordinate 
     //set land to be the pointer to our next empty landmark struct 
     land = whole->landmarks + (sizeof(struct landmark_t) * whole->landcount); 
     set_city_state_country(buf, land); 
     coorflag = 1; //Set flag to get a coordinate line next 
    }else{//We are on a coordinate line which will use 
      //the same land struct pointer as above 
     if(!flagcount){//Have we seen a coordinate line already? 
      land->latitude = number_muncher(buf); 
      flagcount = 1; 
     }else{//We have seen a coordinate line 
      land->longitude = number_muncher(buf); 
      //We are done filling this structure. Reset flags and move to the next. 
      flagcount = 0; 
      coorflag = 0; 
      whole->landcount++; 
     } 
    } 
} 

问题在于grow_whole。我之前遇到过一个问题,那就是在运行realloc之后,第一个里程碑结构将包含正确分配的指针,但之后的任何东西直到文件末尾的某个地方,所有指向城市,州和国家的指针以及经度和纬度都是无效。在我们重新分配之前,我添加了用于保存指向数组的所有指针的for循环,然后将这些指针重写回正确的结构。

void grow_whole(struct wholesome_t *whole) 
{ 
//First collect all of the pointers inside our current landmark structs. 
struct landmark_t *land = NULL; 
char *city[whole->landcount]; 
char *state[whole->landcount]; 
char *country[whole->landcount]; 
float longitude[whole->landcount]; 
float latitude[whole->landcount]; 
for (int i = 0; i < whole->landcount; i++){ 
    land = whole->landmarks + (sizeof(struct landmark_t) * i); 
    city[i] = land->city; 
    state[i] = land->state; 
    country[i] = land->country; 
    longitude[i] = land->longitude; 
    latitude[i] = land->latitude; 
} 
land = realloc(whole->landmarks, (GROW + whole->landmax) * sizeof(struct landmark_t)); 
if(land == NULL){ 
    printf("Error in grow_whole.\n"); 
    return; 
}else{whole->landmarks = land;} 
//Update landmax to represent aftergrow. 
whole->landmax = GROW + whole->landmax; 
//Refill all of the re allocated structs with their pointers. 
for (int i = 0; i < whole->landcount; i++){ 
    land = whole->landmarks + (sizeof(struct landmark_t) * i); 
    land->city = city[i]; 
    land->state = state[i]; 
    land->country = country[i]; 
    land->longitude = longitude[i]; 
    land->latitude = latitude[i]; 
} 
//Fill two new structs with blank data. 
for(int i = whole->landcount; i < whole->landmax; i++){ 
    land = whole->landmarks + (sizeof(struct landmark_t) * i); 
    empty_fill(land); 
} 
return; 
} 

立刻while循环后,上面我们运行

fclose(in); 
char *s = argv[1]; 
s = strtok(s, "."); 
s = strncat(s, ".kml", 4); 
FILE *out = fopen(s, "w"); 
//Finally done lets write some KML 
kml_begin(out); 
for (int i=0; i < whole->landcount; i++){ 
    land = whole->landmarks + (sizeof(struct landmark_t) * i); 
    kml_placemark(out, i, land); 
} 
kml_end(out); 
fclose(out); 
tea_party(whole);//free land 
free(whole->landmarks); 
free(whole); 

它获取到kml_end(出来)。 (我知道,因为我有一个正确的格式与正确的值.kml文件)但在tea_party我得到一个seg_fault。

void tea_party(struct wholesome_t *whole) 
{ 
    struct landmark_t *land = NULL; 
    for (int i = 0; i < whole->landcount; i++){ 
     land = whole->landmarks + (sizeof(struct landmark_t) * i); 
     printf("here\n"); 
     free(land->city); 
     printf("here2\n"); 
     free(land->state); 
     printf("here3\n"); 
     free(land->country); 
    } 
return; 
} 

它发生在我们的第二个标志性结构。

land = whole->landmarks + sizeof(struct landmark_t) 

而在自由(陆地>状态),发生(因为我在这里1-2在这里看到1-3的第一个结构,然后赛格故障之前)。

即使我尝试在seg故障之前打印land-> state,只是将seg故障向上移动。

回答

0

在做指针运算,你没有规模由sizeof(struct landmark_t)偏移 - 编译器已经不适合您!

如果有一个指针p到一个数组,下一个数组元素是在p + 1。就这么简单。

此外,你似乎创建一个数组的记录,当你应该创建一个记录数组。但这是一个不同的问题。

相关问题