使用 `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)
时,您会得到一个未分配给您的无效地址,并且可能会认为其中的所有内容都是垃圾。
我有一个用 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)
时,您会得到一个未分配给您的无效地址,并且可能会认为其中的所有内容都是垃圾。