3

应该是一个简单的问题,我有一个结构

struct Foo{
    float *bar;
    Foo(){
        bar = 0;
    }
};

和一个加载函数:

bool loadFoo(Foo *data){
    float nums[4] = {0,1,2,3};
    data->bar = nums;
    return true;
};

我像这样运行它:

void main(){
    char data;
    Foo myFoo;
    loadFoo(&myFoo);
    std::cerr << sizeof(myFoo.bar) << "\n";
    std::cerr << myFoo.bar[0] << "\n";
    std::cerr << myFoo.bar[1] << "\n";
    std::cerr << myFoo.bar[2] << "\n";
    std::cerr << myFoo.bar[3];
    std::cin >> data;
};

并且 sizeof(myFoo->bar) 的输出是 4 个字节,我认为通过将结构传递给可以修改 data->bar 的方法,并且由于 bar 是,float *bar; 我可以将它设为一个数组,因为我无法指定 bar 是一个数组,因为它在加载时是一个“未知大小”。(实施时,程序将从文件中读取值)这适用于非指针变量,但它的指针我似乎无法理解。

我如何做到这一点,以便在传递结构时可以修改变量指针?

任何帮助将不胜感激!

4

3 回答 3

2

您尚未指定问题,但让我猜猜 - 它崩溃和/或没有产生您期望的结果。原因是在data->bar = nums;此处为行中的局部变量分配了一个指针,您将您链接data->bar到一个nums数组,该数组在堆栈上分配并在您退出时被释放loadFoo。结果是Foo对象内的一个悬空指针。

你可以用不同的方式解决这个问题。最直接的方法是使用带有 size 参数的构造函数 - 这将解决您的unkonwn size问题。您需要显式分配内存data->bar并将数据复制到分配的空间中(当然,不再使用时需要释放它)。使用您的 func 可以实现相同的效果,loadFoo但使用内部语言功能(构造函数/析构函数)要干净得多。

于 2013-09-07T07:23:39.523 回答
2

您可以执行您指定的操作,但您给出的确切实现将遇到未定义的行为。

bool loadFoo(Foo *data){
    // Create an array of 4 floats ON THE STACK.
    float nums[4] = {0,1,2,3};
    // point data->bar at the above slice of stack.
    data->bar = nums;
    return true;
    // abandon the piece of stack we're pointing at.
}

您可能希望将 std::vector 视为一种存储运行时大小数组的可增长方式,或者您需要为目标浮点数分配后备存储,例如

data->bar = new float[4];

完成后释放它

delete data->bar;

那就是说;作为 Foo 的成员执行这些操作似乎更优雅。

#include <vector>
// #include <algorithm>   // (for the std::copy option)

class Foo
{
    std::vector<float>  m_floats;

public:
    Foo() : m_floats() {}
    void loadFloats()
    {
        m_floats = { 0, 1, 2, 3 };
    }
    // or load them from someplace else
    void loadFloats(float* srcFloats, size_t numFloats)
    {
        m_floats.clear();
        m_floats.reserve(numFloats);

        // copy by hand:
        for (size_t i = 0; i < numFloats; ++i) {
            m_floats.push_back(srcFloats[i]);
        }

        // or just:
        // std::copy(srcFloats, srcFloats + numFloats, m_floats);
    }
};
于 2013-09-07T07:30:34.070 回答
1

Instead of loadFoo you can have constructor

struct Foo{
    float *bar;
    Foo( int size){
        bar = new float[size];  //allocate memory
        //... Initialize bar
    }
    ~Foo() { delete bar;}
};

OR using initializer_list

#include <initializer_list>

struct Foo{
    float *bar;
    Foo( std::initializer_list<float> l){
        bar = new float[l.size()];  //allocate memory
        std::initializer_list<float> ::iterator it = l.begin();
        size_t i=0;
        for(;it!=l.end();++it,++i)
          bar[i] = *it;
    }
    ~Foo() { delete bar;}
};

Also, make sure you follow rule of three

于 2013-09-07T07:20:27.477 回答