将struct指针传递给函数c ++

时间:2013-09-07 07:15:50

标签: c++ arrays pointers struct

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

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-&gt; bar)的输出是4个字节我认为通过将结构传递给我可以修改data-&gt; bar的方法,因为bar是,float * bar;我可以把它变成一个数组,因为我不能指定bar是一个数组,因为它在加载时是一个“未知大小”。 (当实现时,程序将读取文件中的值)这适用于非指针变量,但它是我似乎无法理解的指针。

如何制作它以便在我传递结构时可以修改变量指针?

任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:2)

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

您可以通过不同方式解决此问题。最直接的方法是使用带有size参数的构造函数 - 这将解决您的unkonwn size问题。您需要为data->bar显式分配内存并将复制数据分配给已分配的空间(当然,在不使用时需要释放它)。使用loadFoo函数可以实现相同的效果,但使用内部语言功能(构造函数/析构函数)更清晰。

答案 1 :(得分:1)

而不是loadFoo你可以拥有构造函数

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

或使用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;}
};

另外,请务必遵循rule of three

答案 2 :(得分:1)

您可以执行类似于您指定的操作,但您提供的确切实现将遇到未定义的行为。

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);
    }
};