2013-02-25 50 views
2

我正在用C編寫一個程序,它應該從文件中取幾個字符串並將它們放入動態列表中。動態字符串列表的內存分配

出於某種原因(可能是內存分配)每次我試圖把超過十五串到結構時我得到這個錯誤:

*** glibc detected *** ./driver: realloc(): invalid next size: 0x000000000241e250 *** 

的代碼如下:

DLIST。 ħ

struct dlist 
{ 
    int size; 
    int maxSize; 
    char item[1][1024]; 
}; 

#define INITSIZE 6 
#define INCRSIZE 9 
#define DLISTSIZE(n) ((size_t)(sizeof(struct dlist) + (n*1024))) 

struct dlist *initDlist(int num); 
int insDlist(char data[], struct dlist **p); 
void printDlist(struct dlist *p); 
void debugDlist(struct dlist *p); 
int stringCmp(const void *a, const void *b); 

dlist.c

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include "dlist.h" 

struct dlist *initDlist(int num) 
{ 
    struct dlist *p; 

    p = malloc(DLISTSIZE(num)); 

    if(p == NULL) 
     return(NULL); 

    p->size = 0; 
    p->maxSize = num; 
    return(p); 
} 

int insDlist(char data[], struct dlist **p) 
{ 
    struct dlist *q; 

    //printf(" DEBUG: Checking remaining memory.\n"); 

    if ((*p)->size == (*p)->maxSize) 
    { 
     //printf(" DEBUG: Out of memory, reallocating now...\n"); 
     q = realloc(*p, DLISTSIZE((*p)->maxSize + INCRSIZE)); 
     if(q == NULL) 
      return(-1); 

     q->maxSize += INCRSIZE; 
     *p = q; 
    } 

    //printf(" DEBUG: Space available.\n"); 
    int i; 
    (*p)->size++; 

    //adding data to the list 
    for(i = 0; i < 1024; i++) 
     (*p)->item[(*p)->size][i] = data[i]; 

    return(0); 
} 

void printDlist(struct dlist *p) 
{ 
    int i; 
    for(i = 0; i <= p->size; i++) 
     printf("%s", p->item[i]); 
} 

void debugDlist(struct dlist *p) 
{ 
    int i; 

    fprintf(stderr, "\nDynamic List Debug Data\n\n"); 
    fprintf(stderr, " size  = %d\n", p->size); 
    fprintf(stderr, " maxSize = %d\n", p->maxSize); 

    for(i = 0; i <= p->maxSize; i++) 
     fprintf(stderr, "  %s\n", p->item[i]); 
} 

int stringCmp(const void* a, const void* b) 
{ 
    const char *ia = (const char *)a; 
    const char *ib = (const char *)b; 
    return strncmp(ia, ib, 1023); 
} 

driver.c

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include "dlist.h" 

int main(int argc, char *argv[]) 
{ 

    printf("\n"); 

    FILE *fp; 
    char text[1024]; 

    //check the command line 
    if(argc != 2) 
    { 
     fprintf(stderr, "Usage: %s <filename>\n", argv[0]); 
     return(-1); 
    } 

    //open file given on command line 
    fp = fopen(argv[1], "r"); 
    if(fp == NULL) 
    { 
     perror(argv[1]); 
     return(-1); 
    } 

    //initialize the dynamic list 
    struct dlist *p; 
    p = initDlist(INITSIZE); 
    if(p == NULL) 
    { 
     perror("Unable to malloc dlist"); 
     return(-1); 
    } 



    //read each line then store it in the dynamic list 
    while(fgets(text, 1024, fp) != NULL) 
    { 
     //printf("DEBUG: Preparing to insert data.\n"); 
     if(insDlist(text,&p) == -1) 
     { 
      perror("Unable to realloc dlist"); 
      return(-1); 
     } 

     //printf("DEBUG: Data inserted successfully.\n\n"); 
    } 

    //debugDlist(p); 
    printDlist(p); 

    //printf("\nNow sorting...\n\n"); 
    //qsort(&(p->item), p->size, 1, stringCmp); 

    //debugDlist(p); 
    //printDlist(p); 

    return(0); 
} 

任何幫助表示讚賞,在此先感謝。

回答

1

的問題是幾乎可以肯定的是要複製的數據之前遞增列表的大小:也

//adding data to the list 
for(i = 0; i < 1024; i++) 
    (*p)->item[(*p)->size][i] = data[i]; 

(*p)->size++; 

,如果你被允許:

(*p)->size++; 

//adding data to the list 
for(i = 0; i < 1024; i++) 
    (*p)->item[(*p)->size][i] = data[i]; 

你應該重新排列這些語句,以下內容相同:

// adding data to the list 
memcpy((*p)->item[(*p)->size], 
     data, 
     1024); 
(*p)->size++; 

詳細說明,索引是從零開始的。例如,當您分配6個數組時,您將複製到索引[1],[2],[3],[4],[5]和[6]中。

想要複製到索引[0],[1],... [5]。

此外,只有在分配某個特定數字之後才能看到錯誤的原因與堆分配程序有關。

+0

我不敢相信我沒有注意到,我想我已經盯着它太久了。 謝謝,你真的救了我的皮膚。 – 2013-02-25 05:47:08