用`realloc()`重用C数组栈中的整数指针

时间:2017-10-16 10:30:19

标签: c stack 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还是在这种情况下不能这样做?

2 个答案:

答案 0 :(得分:2)

这样做:

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

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

答案 1 :(得分:2)

所以你要求分配内存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)时,您将获得一个无效的地址,该地址未分配给您,并且可能认为其中的所有内容都是垃圾。