使用 `realloc()` 在 C 数组堆栈中重新使用整数指针

re-using integer pointer in C array stack with `realloc()`

我有一个用 C 实现的数组堆栈,我很确定它是正确的。我对以下内容感到困惑。

例如,我可以这样做:

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

int main(void) {
    stack S = Stack();
    int *X = malloc(sizeof(int)*3) ;
    int *Y = malloc(sizeof(int)*5) ;
    int i;
    int *M;

    for (i=0; i<2; i++) {
        X[i] = i*i;
    }
    X[2] = 10*10;

    Push(S, X);

    for (i=0; i<4; i++) {
        Y[i] = 2*i*i;
    }
    Y[4] = 2*10*10;

    Push(S, Y);

    M = Pop(S);
    for (i=0; i<5; i++) { 
        printf("%d - ", M[i]);
    }
    printf("\n");

    M = Pop(S);
    for (i=0; i<3; i++) { 
        printf("%d - ", M[i]);
    }
    printf("\n");

    return 0;
}

打印出来的是:

0 - 2 - 8 - 18 - 200 -
0 - 1 - 100 -

但我做不到:

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

    int main(void) {
    stack S = Stack();
    int *X = malloc(sizeof(int)*3) ;
    int i;
    int *M;

    for (i=0; i<2; i++) {
        X[i] = i*i;
    }
    X[2] = 10*10;

    Push(S, X);

    X = realloc(X, sizeof(int) * 5);

    for (i=0; i<4; i++) {
        X[i] = 2*i*i;
    }
    X[4] = 2*10*10;

    Push(S, X);

    M = Pop(S);
    for (i=0; i<5; i++) { 
        printf("%d - ", M[i]);
    }
    printf("\n");

    M = Pop(S);
    for (i=0; i<3; i++) { 
        printf("%d - ", M[i]);
    }
    printf("\n");

    return 0;
}

打印出:

0 - 2 - 8 - 18 - 200 -
0 - 1610612736 - 0 -

为什么我无法使用指针 X 将多个压入堆栈步骤?我只是错误地使用了 realloc 还是在这种情况下不能这样做?

执行此操作时:

X = realloc(X, sizeof(int) * 5);

不能依赖X的先前值(如果系统能够调整当前内存区域的大小,它可能会保持不变,但这根本不能保证),所以如果你将指针存储在您不能使用您的堆栈 realloc:当 X 内存被移动时,您会得到 未定义的行为

所以你要求分配内存int *X = malloc(sizeof(int)*3)
机器继续为您提供一些 RAM,X 现在的值为 0x1000.
您继续将它推入堆栈 Push(S, X)。现在您的堆栈顶部有 0x1000
然后你要求用 X = realloc(X, sizeof(int) * 5) 重新分配 X。正如@jean-françois-fabre 所说,X 可能会改变。假设它确实发生了变化,现在 X 缓冲区中的所有先前值都被 realloc() 复制到 X 中包含的新地址,假设它是 0x2000。所以你再次将它推入你的堆栈。所以堆栈 S 看起来像这样

  • 0x2000 - 这是分配给 5 个整数的有效地址。
  • 0x1000 - 这是一个 无效的 地址,应该被忽略。

因此,当您执行第二个 Pop(S) 时,您会得到一个未分配给您的无效地址,并且可能会认为其中的所有内容都是垃圾。