繁体   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