【问题标题】:Why are the values stored in memory locations changing?为什么存储在内存位置的值会发生变化?
【发布时间】:2018-08-18 13:48:02
【问题描述】:

我正在尝试实现段树。方式如下:

#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 中打印数组值时,它会显示预期值。然后我返回存储在主函数中的数组的起始地址。现在,当我在 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

【问题讨论】:

  • 我无法重现您的结果,当我运行您的代码时,两组值是相同的。我希望您的代码和您发布的结果不同步。这段代码没有产生这些结果。
  • 好的做法是显式初始化sizes#include&lt;bits/stdc++.h&gt; using namespace std; 也是两个不良做法的例子。这些天你也应该更喜欢nullptr 而不是NULL。还;这看起来更像是用 C++ 编译器编译的 C 代码,而不是 actual 惯用的 C++ - 我建议阅读几本关于 modern C++ 的书。
  • 我更新了代码,一开始我上传了错误的代码。
  • 它被称为“超出范围”。使用std::vector 左右,使这东西返回一个副本。 ofc 不是指针

标签: c++ pointers c++14 dynamic-memory-allocation segment-tree


【解决方案1】:

看看你的代码:

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 然后返回给cons 的调用者。最终b 指向释放的堆栈空间。

后来你有

printf("%d %p\n",b[i],&b[i]);

指的是释放的堆栈。这是未定义的行为。在实践中,printf 的实现重用了释放的堆栈,覆盖了b 的一部分(可能是全部)。这就是为什么读取已释放堆栈是未定义行为的原因。

有几种可能的解决方案。使用并返回std::vector,而不是指针。通常,这是首选解决方案。

在 C 语言中,您可以将指向输出数组的指针传递给 cons。此外,在 C 中,您可以在 cons 中使用 malloc(),并使用它代替 cons 中的 s 数组。您将返回该指针,调用者将负责调用free()。但所有这一切只有在你想坚持 C 习语而不是 C++ 的情况下。

【讨论】:

    猜你喜欢
    • 2014-05-17
    • 1970-01-01
    • 2023-03-14
    • 2020-07-14
    • 2015-04-08
    • 2021-06-29
    • 2013-04-24
    • 2018-12-30
    相关资源
    最近更新 更多