简体   繁体   English

将结构指针传递给函数c ++

[英]passing struct pointers to functions c++

Should be a simple question, I have a struct 应该是一个简单的问题,我有一个结构

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

and a load function: 和加载函数:

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

And I run it like this: 我这样运行:

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

and the output is 4 bytes for the sizeof(myFoo->bar) I thought by passing the struct to the method I could modify data->bar and since bar is, float *bar; 我认为通过将结构传递给可以修改data-> bar的方法,我认为通过将结构传递给sizeof(myFoo-> bar)的4个字节,由于bar是float * bar; I could make it an array since I cant specify that bar is an array because its an 'unknown size' when loaded. 我可以将其设置为数组,因为我不能指定bar为数组,因为它在加载时为“未知大小”。 (when implemented the program will read in values from a file) This works fine with non pointer variables but its the pointer that I can't seem to understand. (在实现时,程序将从文件中读取值)这对于非指针变量可以正常工作,但其指针似乎是我无法理解的。

How do I make it so that when I pass the struct I can modify the variable pointer? 我该如何做,以便在传递结构时可以修改变量指针?

any help would be greatly appreciated! 任何帮助将不胜感激!

You haven't specified the problem but let me guess - it crashes and/or doesn't yield the result you expect. 您尚未指定问题,但让我猜测-它崩溃和/或没有产生您期望的结果。 The reason for that is assigning a pointer to a local variable in the line data->bar = nums; 原因是在行data->bar = nums;分配一个指向局部变量的指针data->bar = nums; Here you link your data->bar to a nums array which is allocated on stack and is freed when you exit loadFoo . 在这里,您将data->bar链接到一个nums数组,该数组分配在堆栈上,并在退出loadFoo时释放。 The result is a dangling pointer inside your Foo object. 结果是在Foo对象中悬挂了一个指针。

You can solve this in different ways. 您可以用不同的方法解决此问题。 The most straightforward would be to use a constructor with size parameter - this will solve your unkonwn size issue. 最直接的方法是使用带有size参数的构造函数-这将解决您unkonwn size问题。 You'll need to explicitly allocate memory for the data->bar and copy the data into the allocated space (of course, it will require to free it when not in use anymore). 您需要为data->bar显式分配内存,并将data->bar 复制到分配的空间中(当然,当不再使用时,将需要释放它)。 Same effect can be achieved by using your loadFoo func but using internal language features (constructor/destructor) is much cleaner. 通过使用loadFoo函数可以达到相同的效果,但是使用内部语言功能(构造函数/析构函数)更加loadFoo

Instead of loadFoo you can have constructor 您可以使用构造函数来代替loadFoo

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

OR using initializer_list 或使用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 另外,请确保遵循以下三个规则

You can do something like you've specified, but the exact implementation you've given will encounter undefined behavior. 您可以执行指定的操作,但是所提供的确切实现将遇到未定义的行为。

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.
}

You might want to look into std::vector as a growable way of storing runtime sizes arrays, or you will need to allocate backing store for the destination floats, eg 您可能想研究std :: vector作为存储运行时大小数组的一种可行方法,否则您将需要为目标float分配后备存储,例如

data->bar = new float[4];

and free it when you are done with it 完成后将其释放

delete data->bar;

That said; 那就是 it would seem more elegant to do these operations as members of Foo. 作为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);
    }
};

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

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