为什么 free(arr) 只删除数组的前两个元素?
Why does free(arr) delete only the first two elements of an array?
我有一个简单的代码:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int elms = 5;
int* a = (int*) calloc(elms, sizeof(int));
*a = elms;
for(int i = 1; i < elms; i++){
*(a + i) = i;
}
for(int i = 0; i < elms; i++){
printf("%d ", *(a + i));
}
printf("\n");
free(a);
// create new array with size increased by one
int* arr = (int*) realloc(a, (elms + 1) * sizeof(int));
*(arr + elms) = 10;
for(int i = 0; i < elms + 1; i++){
printf("%d ", *(arr + i));
}
printf("\n");
return 0;
}
这里我得到的输出是:
5 1 2 3 4
0 0 2 3 4 10
我的问题是为什么调用 free()
只删除数组的前两个元素?要么它应该只删除第一个元素,要么删除所有元素,但为什么要删除两个元素?
如果我评论对 free()
的调用,我会得到预期的输出:
5 1 2 3 4
5 1 2 3 4 10
注意:如果我按预期将 realloc
的值重新分配回 a
,则输出没有变化。
您的代码有未定义的行为。具体来说:
free(a);
... realloc(a, ...);
在free(a)
之后,a
的值不确定。试图用它做任何事情(比如将它传递给一个函数)有未定义的行为。
允许任何结果。
您通过以下方式调用未定义的行为:
free(a);
// create new array with size increased by one
int* arr = (int*) realloc(a, (elms + 1) * sizeof(int));
Per 7.22.3.5 The realloc function, paragraph 3 of the C Standard(加粗我的):
if ptr does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to the free
or realloc
function, the behavior is undefined.
除其他答案外:
你可能想要这个:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int elms = 5;
int* a = (int*)calloc(elms, sizeof(int));
*a = elms;
for (int i = 1; i < elms; i++) {
*(a + i) = i;
}
for (int i = 0; i < elms; i++) {
printf("%d ", *(a + i));
}
printf("\n");
// << don't call free(a) here, once you've done that
// a is "gone" forever.
// create new array with size increased by one
// << we use the same variable a as before, using another
// variable arr as you did is useless and confusing
a = (int*)realloc(a, (elms + 1) * sizeof(int));
*(a + elms) = 10;
for (int i = 0; i < elms + 1; i++) {
printf("%d ", *(a + i));
}
free(a); // << call free(a) here once you're done with a
printf("\n");
return 0;
}
看看<<
开头的评论
输出:
5 1 2 3 4
5 1 2 3 4 10
我有一个简单的代码:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int elms = 5;
int* a = (int*) calloc(elms, sizeof(int));
*a = elms;
for(int i = 1; i < elms; i++){
*(a + i) = i;
}
for(int i = 0; i < elms; i++){
printf("%d ", *(a + i));
}
printf("\n");
free(a);
// create new array with size increased by one
int* arr = (int*) realloc(a, (elms + 1) * sizeof(int));
*(arr + elms) = 10;
for(int i = 0; i < elms + 1; i++){
printf("%d ", *(arr + i));
}
printf("\n");
return 0;
}
这里我得到的输出是:
5 1 2 3 4
0 0 2 3 4 10
我的问题是为什么调用 free()
只删除数组的前两个元素?要么它应该只删除第一个元素,要么删除所有元素,但为什么要删除两个元素?
如果我评论对 free()
的调用,我会得到预期的输出:
5 1 2 3 4
5 1 2 3 4 10
注意:如果我按预期将 realloc
的值重新分配回 a
,则输出没有变化。
您的代码有未定义的行为。具体来说:
free(a);
... realloc(a, ...);
在free(a)
之后,a
的值不确定。试图用它做任何事情(比如将它传递给一个函数)有未定义的行为。
允许任何结果。
您通过以下方式调用未定义的行为:
free(a);
// create new array with size increased by one
int* arr = (int*) realloc(a, (elms + 1) * sizeof(int));
Per 7.22.3.5 The realloc function, paragraph 3 of the C Standard(加粗我的):
if ptr does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to the
free
orrealloc
function, the behavior is undefined.
除其他答案外:
你可能想要这个:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int elms = 5;
int* a = (int*)calloc(elms, sizeof(int));
*a = elms;
for (int i = 1; i < elms; i++) {
*(a + i) = i;
}
for (int i = 0; i < elms; i++) {
printf("%d ", *(a + i));
}
printf("\n");
// << don't call free(a) here, once you've done that
// a is "gone" forever.
// create new array with size increased by one
// << we use the same variable a as before, using another
// variable arr as you did is useless and confusing
a = (int*)realloc(a, (elms + 1) * sizeof(int));
*(a + elms) = 10;
for (int i = 0; i < elms + 1; i++) {
printf("%d ", *(a + i));
}
free(a); // << call free(a) here once you're done with a
printf("\n");
return 0;
}
看看<<
输出:
5 1 2 3 4
5 1 2 3 4 10