2016-03-27 25 views
0

Projemde bu hatayla karşılaştım. aşağıdaki gibi ilgili kodları: aşağıdaki gibi işaretçi "değerleri" için bellek tahsis:C dil hatası munmap_chunk(): geçersiz işaretçi İptal edildi (çekirdek bırakıldı)

aşağıdaki gibi

sonra kullanmadan sonra, değerleri serbest

data->TSSet[0].values = (float *)malloc(sizeof(float)*10000); 
:
free(data->TSSet[0].values); 

Sonra ile bir araya munmap_chunk() hatası: Geçersiz işaretçi İptal edildi (çekirdekli çekirdek).
for(i=0;i<TSSet[0].length;i++) 
    printf("%f\n",TSSet[0].values[i]); 

ben doğru çıktı almak: Ben "değerler" in içeriğini yazdırmak çalıştığınızda çünkü şu gibi işaretçi "değerler", geçerlidir. Hata neden oluyor? Kodun tam sürümü şu şekildedir: (Uzun kodları okumak istemiyorsanız, anahtar bölümüne yorum ekliyorum, sadece yorumlara atla) Ana işlevde, sadece ReadCSV kullanıyorum (dosya, & veri) veri okumak için hemen ResetData (& veri) arayın. Bana yardım ettiğin için hepinize teşekkür ederim !!

void ReadCSV(char *file_path, DATA *Data){ 
    Data->tsname = (char*)malloc(sizeof(char)*MAXNAME); 
    Data->TSSet = (TSItem*)malloc(sizeof(TSItem)*MAXNITEM); 
    FILE *fp = fopen(file_path, "r"); 
    if(fp == NULL) 
     return ; 
    char line[MAXSTRL]; 
    char *save_ptr,*tk; 
    int id = 0, num_class = 0, i,label; 
    Data->ls_class = (int *)malloc(sizeof(int)*MAXC); 
    Data->num_item = 0; 
    Data->length = 0; 
    while(fgets(line, sizeof(line), fp)) { 
     tk = strtok_r(line,",", &save_ptr); 
     if (tk == NULL) 
      return ; 
     label = atoi(trim(tk)); 
     Data->TSSet[id].label = label; 
     Data->TSSet[id].num_nbr = 0; 
     if(IsExist(label,Data->ls_class, num_class) == 0){ 
      Data->ls_class[num_class] = label; 
      num_class++; 
     } 
     // malloc the memory for values 
     Data->TSSet[id].values = (float *)malloc(sizeof(float)*MAXL); 
     Data->TSSet[id].knn = (Neighbor*)malloc(sizeof(Neighbor)*MAXK); 
     i=0; 
     // read in content of values from files 
     while(tk!=NULL){ 
      tk = strtok_r(NULL,",", &save_ptr); 
      Data->TSSet[id].values[i] = strtof(trim(tk),NULL); 
      i++; 
      if(strlen(save_ptr) == 0) 
       break; 
     } 
     Data->TSSet[id].predlbl = -100; 
     Data->TSSet[id].conf = 0.0; 
     Data->TSSet[id].entropy = 0.0; 
     Data->TSSet[id].length = i; 
     id++; 
    } 
    if(fp == NULL) 
     printf("NULL!!!!!!!!!!!!!!!!!!!!!\n"); 
    fclose(fp); 
    Data->num_item = id; 
    Data->length = i; 
    Data->num_class = num_class; 
} 

void ResetData(DATA *data){ 
    int i; 
    free(data->tsname); 
    for(i=0;i<data->num_item;i++){ 
    // error here 
     free(data->TSSet[i].values); 
     free(data->TSSet[i].knn); 
    } 
    free(data->TSSet); 
    data->num_item = 0; 
    data->num_class = 0; 
    free(data->ls_class); 
    data->length = 0; 
    return; 
} 
+0

Veri türü nedir? – greenshade

+0

Bu bir yapı, typedef struct { \t char * tsname; \t TSItem * TSSet; \t int num_item; \t int num_class; \t int * ls_class; \t int uzunluğu; } DATA; – pfc

+0

edit edit ve buraya yapıştır lütfen – greenshade

cevap

0

Benim için sayfadan fırlayan ilk şey, dış döngü sırasında sınır kontrolünün olmamasıdır. Ben minimumda ... çok büyük almıyor kimliği doğrulamak olacaktır:

id hiç tanımlanmamış davranışlar içerisine girmesi başlamak çok büyük alırsa
 while(fgets(line, sizeof(line), fp)) { 
    assert(id < MAXC ); /* (recommend a more "noisy" error message) */ 
    ... 
} 

.

Her alanın malloc() döndürdüğü, onunla ilişkili bir iç "üstbilgisine" sahiptir, bu da en az boştaki baytların serbest bırakılmasını sağlar. Bu şekilde yürürseniz, özellikle ücretsiz() çağrılar her türlü garip şeyler oluşabilir.

+0

Ve eğer id eşit olarak MAXC'ye gidiyorsa, gördüğünüz davranışı alabilirsiniz. – Gilbert

İlgili konular