动态字符串列表的内存分配

时间:2013-02-25 04:51:16

标签: c

我正在用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);
}

提前感谢任何帮助。

1 个答案:

答案 0 :(得分: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]。

此外,仅在分配了一些特定数字后才能看到错误的原因与堆分配器有关。