Realloc地址导致中止(核心转储)

时间:2013-05-27 19:24:00

标签: c realloc memory-address

我尝试在工作代码上实现新功能。但是,我从评论中知道以下几行代码导致我的程序崩溃。

tmp = (char*)realloc(list->array[list->size], sizeof(char)*nameLength);
list->array[list->size] = tmp;

list->array[list->size]在.h文件的结构中定义。 list->size是一个int,随着数组大小的增加而增加。我知道.h文件是正确的,我很确定我的其余代码是正确编写的,因为我测试了所有代码。但是,我似乎无法弄清楚这个realloc函数。有人能帮帮我吗?我搜索了stackoverflow并找不到答案。这是我第一次在stackoverflow上发布一个问题。如果我能帮助解决这个问题,我特此保证在本网站上帮助其他人。

typedef struct ArrayList
{
// We will store an array of strings (i.e., an array of char arrays)
char **array;

// Size of list (i.e., number of elements that have been added to the array)
int size;

// Length of the array (i.e., the array's current maximum capacity)
int capacity;

} ArrayList;

我不想用长代码弄乱帖子。但是,如果有人能找到我忽略的东西,我会发布我的main.c.

int main(void)
{
    int i;
    char buffer[32];
    ArrayList *L1 = createArrayList(-1);

    FILE *ifp = fopen("names.txt", "rb");
    //Read all names from the file and add them to L1.
    while (fscanf(ifp, "%s", buffer) != EOF)
        put(L1, buffer);

    //printf("the size is %d", L1->size);   //test

    for(i=0; i<L1->capacity; i++) { //free columns
        free((void*)L1->array[i]);
    }
    free((void*)L1->array); //free rows
    free((void*)L1); // free struct
    system("pause");
    return 0;
 }

 char * put(ArrayList *list, char *str)
 {
    int i = 0,length = 0, nameLength;
    char* tmp, tmp2;

  //free((void*)list->array[list->size]);   //free columns
  //list->array[list->size] = NULL;         //set old pointer to NULL
    nameLength = strlen(str)+1;             //Aquire length of name +1
    tmp = (char*)realloc(list->array[list->size], sizeof(char)*nameLength);
    list->array[list->size] = tmp;
  //list->array[list->size] = str;
  //strcpy(list->array[list->size], str);
    printf("the name in the .txt file is %s: put \n", list->array[list->size]);

  //if array is full add space
    length = (list->capacity)*2 + 1;
  //if ( list->capacity <= list->size ) {
        ArrayList *nlist = expandArrayList(list, length);
  //}
    list->size ++;
 }

 ArrayList *expandArrayList(ArrayList *list, int length)
 {
    int i;
    //create newCharArray
    char **newCharArray = (char*) malloc(sizeof(char*)*(length+1));  //alocate rows//2
    for(i=0; i<length+1; i++) {  // should fill ten rows + 1//2
        newCharArray[i] = malloc(100 * sizeof(char*));          //alocate Columns
        newCharArray[i] = "yoO";
    }
    //copy old list-Array into newCharArray
    for( i=0; i<list->capacity; i++) { //was length
        newCharArray[i] = list->array[i];
    }
    //print the values you inserted     //test
    for( i=0; i<list->capacity + 1; i++) {//2
        printf("the value in slot %d is %s : expandArrayList \n", i, newCharArray[i]);
    }
    //free the list->array columns and rows
    for( i=0; i<list->capacity; i++) {
        free((void*)list->array[i]);
    }
    free((void*)list->array);
    //set adress of newCh.. = our old Struct
    list->array = newCharArray;
    //print to test we did what was asked //test
    for( i=0; i<length + 1; i++) {//2
        printf("value in slot %d is %s : expandArrayList \n", i, list->array[i]);
    }

    return list;
 }

 ArrayList *createArrayList(int length)
 {
    int ncolumns, nrows, i;
    char stringVar[5]; //set rows = empty
    if(length < DEFAULT_INIT_LEN)
        length = DEFAULT_INIT_LEN;
    nrows = length;

    ArrayList *theArray;
    theArray = (ArrayList*)malloc (sizeof(struct ArrayList));  //alocate struct
    theArray->array = (char*)malloc(sizeof(char*)*(nrows)); //alocate Rows 10th row will be null

    for(i=0; i<nrows; i++) {  // should fill ten rows
        theArray->array[i] = (char*)malloc(2 * sizeof(char)); //alocate Columns //realloc later
        theArray->array[i] = '\0';  //(char*)"pointer char will be returned malloc(100*sizeof(char): char*100 will be alocated
    }

  //theArray->array[nrows] = '\0'; //should fill the 11'th pointer slot array index 10
    theArray->capacity = nrows; //total rows that are available for use ("not including last null")
    theArray->size = 0; //Amount of rows used
    printf("capacity = %d :createArraylist \n", theArray->capacity);

    return theArray;
}

2 个答案:

答案 0 :(得分:1)

在你的expandArrayList()函数中,你在数组中游荡,为字符串分配存储空间。但是,在每次分配之后,您立即丢弃指向已分配存储的指针,并将其替换为指向"yoO"的字符串文字。字符串文字是char的数组,但它们没有使用malloc()分配,不属于您,并且不允许您free()realloc()它们。然而,当你试图释放数组列表的前一个副本时,稍微向下调整相同的函数,猜猜你传递给free()的是什么?

修改

createArrayList()中,你做了几乎相同的事情,除了你丢弃的每个分配的指针,你用'\0'替换,实际上,这是一个空指针。

更不用说,在expandArrayList()中,在用新的malloc()内存片段填充每个插槽后立即(然后扔掉它......),你立即复制指针旧数组列表(您随后也free() ...)

答案 1 :(得分:1)

char **newCharArray = (char*) malloc(sizeof(char*)*(length+1));

你的分配有一个问题,你转而使用char *而不是char **,你的变量名为CharArray,而它是一个C字符串数组。无论如何在C中你不需要转换malloc的返回,只需完全删除转换。

for(i=0; i<length+1; i++) {  // should fill ten rows + 1//2
    newCharArray[i] = malloc(100 * sizeof(char*));          //alocate Columns
    newCharArray[i] = "yoO";
}

expandArrayList中你忘记了一个解除错误的级别,你可能想要:

for(i = 0; i<length+1; i++) {
    newCharArray[i] = malloc(100 * sizeof(char*));
    strcpy(newCharArray[i], "yo0");
}

在createArrayList中你做了同样的错误:

for(i=0; i<nrows; i++) {  // should fill ten rows
    theArray->array[i] = (char*)malloc(2 * sizeof(char)); //alocate Columns //realloc later
    theArray->array[i] = '\0';  //(char*)"pointer char will be returned malloc(100*sizeof(char): char*100 will be alocated
}

你想做这样的事情:

for(i=0; i<nrows; i++) {
    theArray->array[i] = malloc(2);
    *(theArray->array[i]) = '\0';
}