简体   繁体   English

为什么 alloca 两次返回相同的地址?

[英]Why is alloca returning the same address twice?

I'm trying to implement my own math library, and I'm starting off with vectors.我正在尝试实现自己的数学库,并且从向量开始。 The idea is to give the class a pointer to an array of numbers, then copy the array and store it in the data address given by a private variable pointer.想法是给 class 一个指向数字数组的指针,然后复制该数组并将其存储在私有变量指针给出的数据地址中。 To begin with, I used alloca to try and free up some memory for the private variable首先,我使用alloca尝试为私有变量释放一些 memory

vml.h vml.h

namespace vml {
    // Vectors
    template <typename in_type, const int in_length>
    class vec {
    public:
        vec(in_type* in_data) {
            std::cout << data << std::endl;
            std::copy(in_data, in_data + in_length, data);
        }
        vec() {
            data = nullptr;
        }
        in_type& operator()(int index) const {
            _ASSERT(0 <= index && index < in_length);
            return data[index];
        }

    private:
        in_type* data = alloca(in_length * sizeof(in_type));
    };

main.cpp主文件

int main() {
    int list[] = { 1,2,3 };
    int list2[] = {2,4,6 };

    vml::vec<int, 3> a(list);
    vml::vec<int, 3> b(list);

    return 0;
}

This gives no errors however, for some reason, alloca returns the same address twice when calling two instances.这不会产生任何错误,但是由于某种原因, alloca在调用两个实例时会两次返回相同的地址。 I searched this up everywhere and I couldn't find an explanation why.我到处搜索这个,我找不到解释为什么。 So I decided to allocate memory using an array.所以我决定使用数组分配 memory 。 If you can answer this question that would be extremely helpful.如果你能回答这个问题,那将是非常有帮助的。 Thanks.谢谢。

You have to be very careful with alloca .你必须非常小心alloca It allocates memory on the stack rather than the heap.它在堆栈而不是堆上分配 memory。 That memory is freed as soon as the function which called alloca exits.只要调用alloca的 function 退出,就会释放 memory。 In this case, it will be called in the constructor so when you call operator() that memory has already been freed and you are dealing with undefined behavior.在这种情况下,它将在构造函数中调用,因此当您调用operator()时,memory 已经被释放并且您正在处理未定义的行为。

Unless you really need to avoid heap allocations and you know for sure that you wont overflow the stack and you understand all the limitations of using alloca , it's best to steer clear of it.除非您确实需要避免堆分配并且您确定不会溢出堆栈并且您了解使用alloca的所有限制,否则最好避开它。

Lets start with the basics, your stack is most likely only 1 MB, so after a few vectors and recursive calls you program will likely die.让我们从基础开始,您的堆栈很可能只有 1 MB,因此在几个向量和递归调用之后,您的程序可能会死掉。

To solve it if you want it on stack you could use std::array as data如果你想在堆栈上解决它,你可以使用std::array作为data

Warning untested code ahead警告未测试的代码

template <typename in_type, const int in_length>
class vec {
public:
    vec(in_type* in_data) {
        std::cout << data << std::endl;
        std::copy(in_data, in_data + in_length, data);
    }
    vec() = default;
    in_type& operator()(int index) const {
        _ASSERT(0 <= index && index < in_length);
        return data[index];

    }

private:
  std::array<in_type, in_length> data;
};

Alternatively if you want to use all the nice things from std::array或者,如果您想使用std::array中的所有好东西

template <typename in_type, const int in_length>
class vec : public std::array<in_type, in_length> {
public:
  using std::array::array; // use constructors, might need template param to compile
}

This also means that if you at some point just want to change to heap you just allocate your vec as every other class.这也意味着,如果您在某个时候只想更改为堆,您只需像其他 class 一样分配您的 vec。

Another alternative is to use C++17 PMR, use an allocation on the stack as the storage and make vec PMR aware.另一种选择是使用 C++17 PMR,使用堆栈上的分配作为存储并使vec PMR 感知。

You cannot wrap alloca in a function and return its pointer outside, since the stack of wrapper function would be freed.您不能将alloca包装在 function 中并将其指针返回到外部,因为包装器 function 的堆栈将被释放。

If you call it as member initializer, it is actually called from constructor, and may be freed when constructor returns and then re-used.如果将它作为成员初始化器调用,它实际上是从构造函数调用的,并且可能会在构造函数返回时被释放,然后重新使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM