1

私はCでプログラムを書いています。このプログラムは、ファイルからいくつかのテキスト文字列を取得し、それらを動的リスト内に配置することになっています。

何らかの理由(おそらくメモリ割り当て)で、15を超える文字列を構造に入れようとするたびに、このエラーが発生します。

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

コードは次のとおりです。

dlist.h

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);
}

よろしくお願いします。

4

1 に答える 1

1

問題は、データをコピーする前にリストのサイズを増やしていることです。

(*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
for(i = 0; i < 1024; i++)
    (*p)->item[(*p)->size][i] = data[i];

(*p)->size++;

また、許可されている場合は、次のようになります。

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

詳述すると、インデックスはゼロベースです。たとえば、6つのアレイを割り当てる場合は、インデックス[1]、[2]、[3]、[4]、[5]、および[6]にコピーします。

インデックス[0]、[1]、...[5]にコピーします

さらに、特定の番号を割り当てた後にのみエラーが表示される理由は、ヒープアロケータと関係があります。

于 2013-02-25T05:32:01.760 に答える