未分配的int指针未分配C

时间:2018-11-10 11:52:12

标签: c pointers int malloc realloc

我见过其他人问这个,但似乎看不到答案,或者问题出在字符或其他问题上。我真的无法弄清楚为什么会出现此错误,因为我正在分配。我的原始代码更长,但我简化为得到错误的原因,并且即将出现完全相同的错误,所以这就是问题所在。

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

void addInteger(int **iArr, int *newI, int * count);
int main(){
    int* iArr = malloc(0);
    int iCount = 0;
    int newInt = 0;
    int i;
    for(i=0;i<5;i++){
        printf("Enter number: ");
        scanf("%d",&newInt);
        iCount++;
        iArr = realloc(iArr, sizeof(int*) * iCount);
        addInteger(&iArr, &newInt, &iCount);
    }
    free(iArr);
    return 0;
}
void addInteger(int **iArr, int *newI, int * count){

    iArr[*count-1] = malloc(sizeof(int));
    iArr[*count-1] = newI;
}

使用我的输入来运行它会在第二个数字上出现错误:

输入数字:1

输入数字:3

a.out(1291,0x7fffb62df380)malloc:对象0x7ffeed674b78的错误:未分配要重新分配的指针

***在malloc_error_break中设置一个断点进行调试

中止陷阱:6

2 个答案:

答案 0 :(得分:1)

您的取消引用存在一些错误:

变量iArr是指向类型int的数组的指针。

但是您要将其地址传递到addInteger,然后用随机输入值替换此地址。

然后,此随机输入值将传递给realloc而不是您分配的指针,该指针现在消失了。

所以您得到了错误。

让我们修复您的代码来避免这种情况:

//NOTE: there is no need to pass newI and count as pointers, because the function does not change them!
void addInteger(int **iArr, int newI, int count);
int main(){
    //1. If you want iArr to be array of pointers, you need to start with ** pointer to pointer
    //2. Just initialize with NULL, when realloc gets NULL it works just like malloc
    int** iArr = NULL;
    int iCount = 0;
    int newInt = 0;
    int i;

    for(i=0;i<5;i++){
        printf("Enter number: ");
        scanf("%d",&newInt);
        iCount++;
        iArr = realloc(iArr, sizeof(int*) * iCount);
        //You do not need to pass addresses here because your function does not change its parameters
        addInteger(iArr, newInt, iCount);
    }

    free(iArr); //this will cause a memory leak!
    //you need to loop over the array and free each integer first.

    return 0;
}

void addInteger(int **iArr, int newI, int count){
    iArr[count - 1] = malloc(sizeof(int));
    *iArr[count - 1] = newI;
    /* Note the * here - it is important!
       Without it, you would overwrite the pointer you just allocated in the prevoius line
       But the * tells the compiler "put the int value at the address specified by the array
    */
}

答案 1 :(得分:0)

让我们一次在程序中执行一个语句。

int* iArr = malloc(0);

iArrNULL或指向大小为0的对象。

int iCount = 0;
int newInt = 0;
int i;
for(i=0;i<5;i++){

在第一次迭代中,我们有i = 0

    printf("Enter number: ");
    scanf("%d",&newInt);

假设用户在此处输入了42,因此newInt = 42

    iCount++;

现在iCount = 1

    iArr = realloc(iArr, sizeof(int*) * iCount);

这很可疑:iArr被声明为指向int的指针(可以用来指向整数数组),但是您没有为iCount整数分配空间,重新为iCount指向int的指针分配空间。

如果iArr是一个指向int的动态指针数组,则应将其声明为     int ** iArr;

如果iArr是一个int的动态数组,则此调用应更改为

iArr = realloc(iArr, sizeof (int) * iCount);

或(最好):

iArr = realloc(iArr, sizeof *iArr * iCount);

无论声明如何iArr,后一种形式总是正确的 1

(将NULL作为第一个参数传递给realloc很好,所以最初返回的malloc(0)到底是什么都没关系。)

    addInteger(&iArr, &newInt, &iCount);

让我们在此内联此函数(我更改了参数名称以使其更清楚地显示正在发生的事情):

    int **addInteger_iArr = &iArr;
    int *addInteger_newI = &newInt;
    int *addInteger_count = &iCount;

我们初始化函数参数。

    addInteger_iArr[*addInteger_count-1] = malloc(sizeof(int));

好的,这行实际上是做什么的?我们知道addInteger_count的值;是&iCount,所以我们将其插入:

    addInteger_iArr[*(&iCount)-1] = malloc(sizeof(int));

*&互相抵消,给出:

    addInteger_iArr[iCount-1] = malloc(sizeof(int));

iCount1,而1-10,因此变成:

    addInteger_iArr[0] = malloc(sizeof(int));

类似地,让我们插入addInteger_iArr的值,即&iArr

    (&iArr)[0] = malloc(sizeof(int));

a[b]由C定义为*(a + b),所以此行的意思是:

    *(&iArr + 0) = malloc(sizeof(int));

添加0不会执行任何操作,而*&会互相抵消,所以我们得到:

    iArr = malloc(sizeof(int));

嘿!我们刚刚失去了iArr的旧值(realloc返回的指针)。这是内存泄漏。

    addInteger_iArr[*addInteger_count-1] = addInteger_newI;

赋值的左侧与前面的语句相同; addInteger_newI&newInt相同:

    iArr = &newInt;

嘿!我们只是失去了旧值iArr(上一条语句中malloc返回的指针)。这是另一次内存泄漏。

此外,iArr不再指向动态分配的内存;它指向newInt,它只是一个局部变量。

}

现在,我们开始循环的第二次迭代。这会在realloc(iArr, ...)中崩溃,因为此时iArr被设置为&newInt


有几种方法可以修复此代码。

如果只需要一个简单的动态整数数组,则应将循环更改为:

    iCount++;
    iArr = realloc(iArr, iCount * sizeof *iArr);
    iArr[iCount-1] = newInt;

如果要将最后一条语句移到函数中,则:

    addInteger(iArr, iCount, newInt);

使用

void addInteger(int *iArr, int iCount, int newInt) {
    iArr[iCount-1] = newInt;
}

1 嗯,大小计算是正确的。您仍然需要检查realloc是否失败,在这种情况下它会返回NULL,并且您需要手动free指针,并且通常应该检查{{1 }}计算。