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

驱动程序.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 回答