[edit]在这个get方法之外(见下文),我想要一个指针double * result;
,然后调用get方法,即
// Pull results out
int story = 3;
double * data;
int len;
m_Scene->GetSectionStoryGrid_m(story, data, len);
据说,我想要一个get方法,它只是通过引用设置结果(*& data),而不是动态分配内存。
我正在寻找的结果已经存在于内存中,但它们在C结构中并且不在一个连续的内存块中。 Fyi,& len只是阵列的长度。我想要一个包含所有结果的大数组。
由于我要查找的实际结果存储在本机C结构指针story_ptr->int_hv[i].ab.center.x;
中。我如何避免像上面那样动态分配内存?我想将数据*指向结果,但我不知道该怎么做。这可能是我想要的简单......代码如下。
这甚至可能吗?从我所读到的,它不是,但正如我的用户名暗示,我不是软件开发人员。感谢所有到目前为止回复的人!
以下是一段代码:
void GetSectionStoryGrid_m( int story_number, double *&data, int &len )
{
std::stringstream LogMessage;
if (!ValidateStoryNumber(story_number))
{
data = NULL;
len = -1;
}
else
{
// Check to see if we already retrieved this result
if ( m_dStoryNum_To_GridMap_m.find(story_number) == m_dStoryNum_To_GridMap_m.end() )
{
data = new double[GetSectionNumInternalHazardVolumes()*3];
len = GetSectionNumInternalHazardVolumes()*3;
Story * story_ptr = m_StoriesInSection.at(story_number-1);
int counter = 0; // counts the current int hv number we are on
for ( int i = 0; i < GetSectionNumInternalHazardVolumes() && story_ptr->int_hv != NULL; i++ )
{
data[0 + counter] = story_ptr->int_hv[i].ab.center.x;
data[1 + counter] = story_ptr->int_hv[i].ab.center.y;
data[2 + counter] = story_ptr->int_hv[i].ab.center.z;
m_dStoryNum_To_GridMap_m.insert( std::pair<int, double*>(story_number,data));
counter += 3;
}
}
else
{
data = m_dStoryNum_To_GridMap_m.find(story_number)->second;
len = GetSectionNumInternalHazardVolumes()*3;
}
}
}
答案 0 :(得分:4)
考虑返回自定义访问者类而不是“double *&amp; data”。根据您的需要,该类看起来像这样:
class StoryGrid {
public:
StoryGrid(int story_index):m_storyIndex(story_index) {
m_storyPtr = m_StoriesInSection.at(story_index-1);
}
inline int length() { return GetSectionNumInternalHazardVolumes()*3; }
double &operator[](int index) {
int i = index / 3;
int axis = index % 3;
switch(axis){
case 0: return m_storyPtr->int_hv[i].ab.center.x;
case 1: return m_storyPtr->int_hv[i].ab.center.y;
case 2: return m_storyPtr->int_hv[i].ab.center.z;
}
}
};
对于任何语法问题感到抱歉,但您明白了。返回对此的引用并将其记录在地图中。如果正确完成了地图,则管理所需的所有动态分配。
答案 1 :(得分:2)
所以你希望分配的数组在调用堆栈中“向下”。您只能使用动态分配在堆中分配它。或创建static
变量,因为static
变量的生命周期不受调用堆栈的控制。
void GetSectionStoryGrid_m( int story_number, double *&data, int &len )
{
static g_data[DATA_SIZE];
data = g_data;
// continues ...
如果您想“避免任何分配”,@ Speed8ump的解决方案是您的首选!但是你不再拥有double * result;
了。您将转向“离线”解决方案(首先计算整个阵列,然后在其他地方使用阵列)到“在线”解决方案(根据需要计算值)。这是一个很好的重构,可以避免内存分配。
答案 2 :(得分:0)
这个问题的答案取决于你想要指针的double
的生命周期。考虑:
// "pointless" because it takes no input and throws away all its work
void pointless_function()
{
double foo = 3.14159;
int j = 0;
for (int i = 0; i < 10; ++i) {
j += i;
}
}
foo
存在并且在pointless_function
内有一个值,但一旦函数退出就会停止存在。即使你可以获得指向它的指针,该指针在pointless_function
之外也是无用的。它将是一个悬空指针,取消引用它将触发undefined behavior。
另一方面,你是正确的如果你有内存中的数据(并且你可以保证它能活得足够长,无论你想做什么),它都可以很棒想要获得指向该数据的指针而不是支付复制它的成本。但是,数据生成创建函数的主要方式是调用new
,new[]
或malloc
。你真的无法摆脱它。
查看您发布的代码,我看不出您在创建new[]
时如何避免story
- 双打。但是,您可以稍后获得指向这些双打的指针,而无需再次致电new
或new[]
。
我应该提一下,指向数据的指针可以用来修改原始数据。通常这会导致难以追踪的错误。所以有时候最好付出复制数据的价格(然后你可以自由地捣乱),或者获得指向const的指针(在这种情况下是const double*
或{ {1}},它们是等价的;如果你试图改变指向的数据,指向const的指针会给你一个编译错误。实际上,通常情况下建议应该颠倒过来:“有几次你不想要复制或获得指向const的指针;在这种情况下你必须要非常小心。“