为什么存储在内存位置的值会发生变化?
Why are the values stored in memory locations changing?
我正在尝试实现线段树。通过以下方式:
#include<bits/stdc++.h>
using namespace std;
int size;
int construct(int *arr,int *s,int curr,int end,int ad)
{
if(arr[curr]==arr[end])
{
s[ad]=arr[curr];
return s[ad];
}
int mid=(curr+end)/2;
s[ad]=construct(arr,s,curr,mid,ad*2+1)+construct(arr,s,mid+1,end,ad*2+2);
return s[ad];
}
int* cons(int *arr,int n)
{
int height=ceil(log2(n));
size=(int)(2*pow(2,height)-1);
int s[(int)(2*pow(2,height)-1)]={0};
construct(arr,s,0,n-1,0);
//printf("\n In cons function \n\n");
for (int i = 0; i <size; ++i)
{
printf("%d %p\n",s[i], &s[i] );
}
int *po=s;
printf("\n%p %d\n",po,size );
return po;
}
int main()
{
int arr[6]={1,3,5,7,9,11};
int *b=cons(arr,6);
printf("%p %d\n\n",b,size );
//printf("\n\n In main function \n\n");
for (int i = 0; i <size; ++i)
{
printf("%d %p\n",b[i],&b[i]);
}
return 0;
}
当我在函数 cons 中打印数组值时,它显示预期值。然后我 return 我存储在 main 函数中的数组的起始地址。现在当我在 main 函数中打印相同的值时,有些值是不同的,即使存储值的地址保持不变。
这是一个示例输出:
36 0x7ffce0eb6130
9 0x7ffce0eb6134
27 0x7ffce0eb6138
4 0x7ffce0eb613c
5 0x7ffce0eb6140
16 0x7ffce0eb6144
11 0x7ffce0eb6148
1 0x7ffce0eb614c
3 0x7ffce0eb6150
0 0x7ffce0eb6154
0 0x7ffce0eb6158
7 0x7ffce0eb615c
9 0x7ffce0eb6160
0 0x7ffce0eb6164
0 0x7ffce0eb6168
0x7ffce0eb6130 15
0x7ffce0eb6130 15
36 0x7ffce0eb6130
9 0x7ffce0eb6134
9 0x7ffce0eb6138
0 0x7ffce0eb613c
-521445060 0x7ffce0eb6140
32764 0x7ffce0eb6144
20 0x7ffce0eb6148
0 0x7ffce0eb614c
0 0x7ffce0eb6150
0 0x7ffce0eb6154
18 0x7ffce0eb6158
0 0x7ffce0eb615c
9 0x7ffce0eb6160
0 0x7ffce0eb6164
0 0x7ffce0eb6168
看看你的代码:
int* cons(int *arr,int n)
{
....
int s[(int)(2*pow(2,height)-1)]={0};
...
int *po=s;
printf("\n%p %d\n",po,size );
return po;
}
由
调用
int *b=cons(arr,6);
这里,po
是指向s
第一个元素的指针。这个指向局部变量的 po
然后被 returned 给 cons
的调用者。最终 b
指向已释放堆栈 space.
稍后你有
printf("%d %p\n",b[i],&b[i]);
指释放栈。这是未定义的行为。实际上,printf 的实现重用了已释放的堆栈,覆盖了 b
的部分(可能是全部)。这就是为什么读取已释放的堆栈是未定义的行为。
有几种可能的解决方案。使用 and return std::vector
,而不是指针。通常,这是首选解决方案。
在 C 中,您可以将指向输出数组的指针传递给 cons
。此外,在 C 中,您可以在 cons
中使用 malloc()
,并使用它代替 cons
中的 s
数组。您将 return 该指针,而调用者将负责调用 free()
。但是所有这一切只有当你想坚持使用 C 习语而不是 C++ 时。
我正在尝试实现线段树。通过以下方式:
#include<bits/stdc++.h>
using namespace std;
int size;
int construct(int *arr,int *s,int curr,int end,int ad)
{
if(arr[curr]==arr[end])
{
s[ad]=arr[curr];
return s[ad];
}
int mid=(curr+end)/2;
s[ad]=construct(arr,s,curr,mid,ad*2+1)+construct(arr,s,mid+1,end,ad*2+2);
return s[ad];
}
int* cons(int *arr,int n)
{
int height=ceil(log2(n));
size=(int)(2*pow(2,height)-1);
int s[(int)(2*pow(2,height)-1)]={0};
construct(arr,s,0,n-1,0);
//printf("\n In cons function \n\n");
for (int i = 0; i <size; ++i)
{
printf("%d %p\n",s[i], &s[i] );
}
int *po=s;
printf("\n%p %d\n",po,size );
return po;
}
int main()
{
int arr[6]={1,3,5,7,9,11};
int *b=cons(arr,6);
printf("%p %d\n\n",b,size );
//printf("\n\n In main function \n\n");
for (int i = 0; i <size; ++i)
{
printf("%d %p\n",b[i],&b[i]);
}
return 0;
}
当我在函数 cons 中打印数组值时,它显示预期值。然后我 return 我存储在 main 函数中的数组的起始地址。现在当我在 main 函数中打印相同的值时,有些值是不同的,即使存储值的地址保持不变。
这是一个示例输出:
36 0x7ffce0eb6130
9 0x7ffce0eb6134
27 0x7ffce0eb6138
4 0x7ffce0eb613c
5 0x7ffce0eb6140
16 0x7ffce0eb6144
11 0x7ffce0eb6148
1 0x7ffce0eb614c
3 0x7ffce0eb6150
0 0x7ffce0eb6154
0 0x7ffce0eb6158
7 0x7ffce0eb615c
9 0x7ffce0eb6160
0 0x7ffce0eb6164
0 0x7ffce0eb6168
0x7ffce0eb6130 15
0x7ffce0eb6130 15
36 0x7ffce0eb6130
9 0x7ffce0eb6134
9 0x7ffce0eb6138
0 0x7ffce0eb613c
-521445060 0x7ffce0eb6140
32764 0x7ffce0eb6144
20 0x7ffce0eb6148
0 0x7ffce0eb614c
0 0x7ffce0eb6150
0 0x7ffce0eb6154
18 0x7ffce0eb6158
0 0x7ffce0eb615c
9 0x7ffce0eb6160
0 0x7ffce0eb6164
0 0x7ffce0eb6168
看看你的代码:
int* cons(int *arr,int n)
{
....
int s[(int)(2*pow(2,height)-1)]={0};
...
int *po=s;
printf("\n%p %d\n",po,size );
return po;
}
由
调用int *b=cons(arr,6);
这里,po
是指向s
第一个元素的指针。这个指向局部变量的 po
然后被 returned 给 cons
的调用者。最终 b
指向已释放堆栈 space.
稍后你有
printf("%d %p\n",b[i],&b[i]);
指释放栈。这是未定义的行为。实际上,printf 的实现重用了已释放的堆栈,覆盖了 b
的部分(可能是全部)。这就是为什么读取已释放的堆栈是未定义的行为。
有几种可能的解决方案。使用 and return std::vector
,而不是指针。通常,这是首选解决方案。
在 C 中,您可以将指向输出数组的指针传递给 cons
。此外,在 C 中,您可以在 cons
中使用 malloc()
,并使用它代替 cons
中的 s
数组。您将 return 该指针,而调用者将负责调用 free()
。但是所有这一切只有当你想坚持使用 C 习语而不是 C++ 时。