0

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

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

2 回答 2

1

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

编辑

createArrayList()中,您几乎执行相同的操作,除了您丢弃的每个分配的指针,您将替换为'\0',这实际上是此上下文中的空指针。

更不用说,在expandArrayList()用新的内存填充每个插槽malloc()(然后将其丢弃......)之后,如何立即从旧数组列表中复制指针(您随后也free()......)

于 2013-05-27T20:06:57.197 回答
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';
}
于 2013-05-27T20:17:37.300 回答