我有一个用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还是在这种情况下不能这样做?
答案 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)
时,您将获得一个无效的地址,该地址未分配给您,并且可能认为其中的所有内容都是垃圾。