【问题标题】:How to allocate a struct and then increase its size?如何分配结构然后增加其大小?
【发布时间】:2015-04-10 09:54:29
【问题描述】:

我有一个结构数据

struct dataStruct{
  int mID;
  float mX;
};

一个fillData方法

void fillData(data *pt)
{
  pt = new data(10);
}

main函数

int main(int argc, char** argv)
{
  dataStruct *myData;
  fillData(myData);

  myData[4].mID = 10;

  std::cout <<  myData[4].mID << " " << myData[5].mID << std::endl;
}

还有几个问题:

  • 如何在 fillData 方法中分配 myData 以使分配不是 fillData 的本地分配?
  • myData 的大小是否可以通过以后调用 fillData增加,从而将大小从 10 更改为 100?
  • 使用 std::unique_ptr 管理 dataStruct 指针会更好吗?

【问题讨论】:

  • 使用指针参数的引用:void fillData(data*&amp; pt)
  • 对于 C++ 问题,这是非常 C 的。使用例如std::vector 完成。
  • "如何分配结构然后增加它的大小?" 你不能在运行时增加结构的大小。
  • 在需要重新分配时使用 malloc 和 realloc
  • 你的意思可能是void fillData(data*&amp; pt) { pt = new data[10]; }

标签: c++ memory struct new-operator


【解决方案1】:

我猜你想要什么,因为不清楚。

这是处理大小需要动态更改的对象集合的更好方法:

struct dataStruct
{
    dataStruct() : mID(0), mX(0.0f) {} // default to value 0

    dataStruct(int mID, float mX) : mID(mID), mX(mX) {}

    int mID;
    float mX;
};

int main(int argc, char** argv)
{   
    std::vector<dataStruct> myData(10); // create 10 objects with values 0

    myData[4].mID = 10;

    std::cout <<  myData[4].mID << " " << myData[5].mID << std::endl;

    // now resize to 100 objects, with 0 values for any new objects
    myData.resize(100);

    std::cout <<  myData[4].mID << " " << myData[99].mID << std::endl;
}

现场示例: http://ideone.com/5nyPOp

没有内存泄漏!没有未初始化的数据(在您的原始代码中使用)。好的调试编译器会为你做边界检查。

【讨论】:

  • 哇,非常好的回应。所以基本上你创建了一个包含 dataStruct 对象的向量。有人可以 push_back 对象到向量,而不是添加前 10 个然后重新调整大小为 100?另外,我不确定以下行的作用: dataStruct(int mID, float mX) : mID(mID), mX(mX) {}
  • @charis 是的,您可以单独调整大小或 push_back。那是一个使用初始化列表的构造函数。
【解决方案2】:

对于第一个问题,fillData() 需要接受一个参考

void fillData(data *&pt)      // makes change of pt visible to the caller
{
  pt = new data(10);
}

int main()
{
    data *pointer;
    fillData(pointer);
}

或指向指针的指针

void fillData(data **pt)      // makes change of *pt visible to the caller
{
  *pt = new data(10);
}

int main()
{
    data *pointer;
    fillData(&pointer);    // pass the address of pointer
}

对于第二个问题,不知何故,fillData() 需要被告知要分配多少对象,并且能够释放。

void fillData(data *&pt, int size)
{
    delete [] pt;
    pt = new data[size];
}

int main()
{
    data *pointer = NULL;    //  otherwise first call of fillData() will fail on the delete statement

    fillData(10);
     //   use pointer like an array of 10 elements

    fillData(20);   //   note previous contents of pointer are lost

     //   use pointer like an array of 10 elements
}

回答你的第三个问题:简答:否。

第三个问题的更长答案:如果您想要一组可调整大小的 data,请改用标准容器(如 std::vector&lt;data&gt;)。这样做的一个优点是可以干净地调整标准容器的大小(例如,如果将大小从 10 个元素调整到 20 个元素,则保留前 10 个元素)。

注意:可以调整直接使用operator new 分配的东西的大小(例如,使用额外的簿记来跟踪当前和新的大小)但我在上面的示例中没有这样做 - 因为使用标准容器是在实践中是一种更好的方法。

【讨论】:

  • 感谢您的详细回复!
猜你喜欢
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 2016-04-06
  • 2017-07-28
  • 2021-06-04
  • 2019-04-05
  • 1970-01-01
相关资源
最近更新 更多