我正在用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);
}
提前感谢任何帮助。
答案 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]。
此外,仅在分配了一些特定数字后才能看到错误的原因与堆分配器有关。