簡體   English   中英

動態數組:error free():下一個大小無效(快速),分段錯誤(核心已轉儲)

[英]Dynamic Array: error free(): invalid next size (fast), Segmentation fault (core dumped)

所以我試圖讓用戶輸入數字,然后將該值存儲在動態數組中。 下面是代碼:

#include <stdio.h>
#include <stdlib.h>

//dynamically grow the array 
void growArray(int *arr, int *size){
    //double the size of the array
    printf("Resizing array\n");
    int *temp = malloc( *size * 2 * sizeof(int)); 
    printf("Malloc was succesfuly\n");
    int i; 
    for (i = 0; i < *size; i++)
        temp[i] = arr[i]; 

    printf("About to free arr\n");
    printf("arr: %p", arr); 
    printf("temp: %p", temp);
    free(arr);
    arr = malloc( *size * 2 * sizeof(int)); 
    printf("About to change value to arr\n");
    arr = temp; 
    free(temp);
    printf("About to change the value of size\n");
    *size *= 2; 
    printf("New size: %d\n", *size);
}


int main(){

    int *dynamicArr; 
    int *size; 
    *size = 1; 
    dynamicArr = (int*) malloc(sizeof(int));

    int value, i;
    i = 0; 
    do{
        printf("\nPlease enter in a int value: ");
        scanf("%d", &value); 

        //check if the array needs to be resizesd;
        printf("Checking if size if sufficient\n");
        if (i >= *size)
            growArray(dynamicArr, size);

        if (value != -999){
            printf("Adding value to the array\n");
            dynamicArr[i] = value;
            i ++; 
        }
    }while(value != -999); 

    for (i = 0; i < *size; i++){
        printf("Value of dynamicArr[%d]: %d\n", i, dynamicArr[i]);
    }

    return 0; 
}

如您所見,我有一堆打印語句,因此我可以看到我的程序在什么時候以及當前正在做什么。 因此,該程序最初可以運行。 我能夠成功添加8個值(並調整數組大小3次,從大小1變為大小8)。 但是,當我添加9值時,它必須調整數組的大小,在該數組中調用方法growArray()。 但是,由於某種原因,我得到以下錯誤:

*** Error in `./a.out': free(): invalid next size (fast): 0x0000000000e69010 ***
Segmentation fault (core dumped)

在發生錯誤之前,printf(“ About to free arr”)有效,但是printf(“ arr:%p”,arr); 不被調用。

我不知道為什么會這樣,有些幫助將不勝感激。

您的代碼應該看起來更像這樣:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int size = 1;
    int *dynamicArr = malloc(size * sizeof(*dynamicArr));

    int idx = 0;
    while (1) {
        int value;
        printf("\nPlease enter in a int value: ");
        scanf("%d", &value);

        if (value == -999) {
            break;
        }

        //check if the array needs to be resizesd
        printf("Checking if size if sufficient\n");
        if (idx >= size) {
            size *= 2;
            dynamicArr = realloc(dynamicArr, size * sizeof(*dynamicArr));
        }

        printf("Adding value to the array\n");
        dynamicArr[idx++] = value;
    }

    int i;
    for (i = 0; i < idx; i++) {
        printf("Value of dynamicArr[%d]: %d\n", i, dynamicArr[i]);
    }

    free(dynamicArr);
    return 0; 
}

或者,如果您要堅持實施:

#include <stdio.h>
#include <stdlib.h>

//dynamically grow the array 
void growArray(int **arr, int *size){
    //double the size of the array
    printf("Resizing array\n");
    int *temp = malloc( *size * 2 * sizeof(int)); 
    printf("Malloc was succesfuly\n");
    int i;
    for (i = 0; i < *size; i++)
        temp[i] = (*arr)[i];

    printf("About to free arr\n");
    printf("arr: %p\n", *arr); 
    printf("temp: %p\n", temp);
    free(*arr);
    printf("About to change value to arr\n");
    *arr = temp;
    printf("About to change the value of size\n");
    *size *= 2;
    printf("New size: %d\n", *size);
}


int main() {
    int size = 1;
    int *dynamicArr = malloc(size * sizeof(*dynamicArr));

    int idx = 0;
    while (1) {
        int value;
        printf("\nPlease enter in a int value: ");
        scanf("%d", &value);

        if (value == -999) {
            break;
        }

        //check if the array needs to be resizesd;
        printf("Checking if size if sufficient\n");
        if (idx >= size) {
            growArray(&dynamicArr, &size);
        }

        printf("Adding value to the array\n");
        dynamicArr[idx++] = value;
    }

    int i;
    for (i = 0; i < idx; i++){
        printf("Value of dynamicArr[%d]: %d\n", i, dynamicArr[i]);
    }

    free(dynamicArr);
    return 0; 
}

順便說一句,您可以使用memcpy將整個現有陣列復制到temp陣列。

您的原始代碼中有兩個問題。

(a)參數arr按值傳遞給growArray ,因此您的賦值arr = malloc(...)arr = temp不會僅更新growArray本地副本的main()引用的變量。 另一方面,當您調用free(arr)您正在釋放main()變量dynamicArr指向的緩沖區。 這是造成段錯誤的直接原因。

(b)當您分配arr = temp然后free(temp); 您泄漏了上面剛剛分配的malloc()緩沖區,然后釋放了分配給arr的緩沖區(使其懸空)。

void growArray(int *arr, int *size){

當輸入growArrayarr指向緩沖區A

    ...
    int *temp = malloc( *size * 2 * sizeof(int));

temp初始化為指向新的緩沖區B

    ...
    free(arr);

原始緩沖區A被釋放。 現在,局部變量arr是一個懸空指針,調用者持有的指針(通過值傳遞到該例程中的指針)也是如此。

    arr = malloc( *size * 2 * sizeof(int)); 

arr設置為新分配的緩沖區C。

    ...
    arr = temp; 

arr設置為別名temp ,指向緩沖區B。緩沖區C泄漏。

    free(temp);

釋放由temparr指向的緩沖區B。 他們現在都是懸空的指針。 arr之后

    ...
}

tmparr都超出范圍。 緩沖區B和C泄漏。

int main(){

    int *dynamicArr; 
    int *size; 
    *size = 1; 
    dynamicArr = (int*) malloc(sizeof(int));

dynamicArr指向已分配的緩沖區... do {... if(...){growArray(dynamicArr,size); ...}

如果條件條件第一次通過,則將dynamicArr的值作為參數arr傳遞給growArray。 growArray釋放它指向的緩沖區,然后分配並泄漏一些內存,而不會影響dynamicArr的局部值。 dynamicArr現在是一個懸空指針。

        if (value != -999){
            ...
            dynamicArr[i] = value;

然后訪問懸空的指針和段錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM