在c ++中返回一个struct数组,并将该数组传递给另一个方法?

时间:2014-01-09 17:03:05

标签: c++ arrays function struct

我需要返回一个结构数组,然后将这个数组传递给另一个打印方法。

这是我的.h文件:

#include <string>
#include "COMMON_TYPES.h"

#pragma once
#pragma pack(push, 1)

 class ARS_HR_LINE_1
{
public:
    struct ARS_HR_LINE_1_ALL
    {
        //Countre
        int     Counter
        float       Inner_Rate_FB_Fine;
        float           Inner_Rate_FB_Cross;
        float           Inner_Rate_FB_Roll;
        float           IMU_Yaw;
    };

    u16 img [1][616];

    //Methods
    ARS_HR_LINE_1::ARS_HR_LINE_1_ALL  *Process_HR_ARS_Line_1(); 
    void                              Print_HR_Line_1(FILE* fptr, int counter, ARS_HR_LINE_1::ARS_HR_LINE_1_ALL* h);    // Print High Rate Line 1
    };

#pragma pack(pop)

.cpp文件:

#include <iostream>
#include "ARS_HR_LINE_1.h"
#include "COMMON_TYPES.h"

using namespace std;

ARS_HR_LINE_1::ARS_HR_LINE_1_ALL * ARS_HR_LINE_1::Process_HR_ARS_Line_1()
{
    ARS_HR_LINE_1::ARS_HR_LINE_1_ALL h[60];

    for(int i=0;i<60;++i)
    {
        h[i].Counter = (ARS_HR_LINE_1::img[0][i*10 + 0] << 16) + ARS_HR_LINE_1::img[0][i*10 + 1];

        u32 inner_rate_fb_fine = (ARS_HR_LINE_1::img[0][i*10 + 2] << 16) + ARS_HR_LINE_1::img[0][i*10+3];
        h[i].Inner_Rate_FB_Fine =*reinterpret_cast<float*>(&inner_rate_fb_fine);

        u32 inner_rate_fb_cross = (ARS_HR_LINE_1::img[0][i*10+4] << 16) + ARS_HR_LINE_1::img[0][i*10+5];
        h[i].Inner_Rate_FB_Cross =*reinterpret_cast<float*>(&inner_rate_fb_cross);

        u32 inner_rate_fb_roll = (ARS_HR_LINE_1::img[0][i*10+6] << 16) + ARS_HR_LINE_1::img[0][i*10+7];
        h[i].Inner_Rate_FB_Roll =*reinterpret_cast<float*>(&inner_rate_fb_roll);

        u32 imu_yaw = (ARS_HR_LINE_1::img[0][i*10+8] << 16) + ARS_HR_LINE_1::img[0][i*10+9];
        h[i].IMU_Yaw =*reinterpret_cast<float*>(&imu_yaw);
    }
    return h;
}

void ARS_HR_LINE_1::Print_HR_Line_1(FILE* fptr, int counter, ARS_HR_LINE_1::ARS_HR_LINE_1_ALL *h)
{
    ARS_HR_LINE_1::ARS_HR_LINE_1_ALL temp;

    temp.Counter = 0;
    temp.Inner_Rate_FB_Fine = 0;
    temp.Inner_Rate_FB_Cross = 0;
    temp.Inner_Rate_FB_Roll = 0;
    temp.IMU_Yaw = 0;

    //tempArr[i] = *(h+i);
    fprintf(fptr, "************************************************************\n");
    fprintf(fptr, "******************IMAGE NUMBER %d ***************************\n", counter);


fprintf(fptr, "*********************LINE 1**********************************\n");

for(int i=0;i<60;++i)
{   
    temp = *(h+i);
    //Counter and Filler - 4 bytes
    fprintf(fptr, "Counter[%d]                                      : %u\n", temp.Counter, i);

    //Rate FB
    fprintf(fptr, "Inner_Rate_FB_Fine[%d]                           : %12.20f\n", temp.Inner_Rate_FB_Fine, i);
    fprintf(fptr, "Inner_Rate_FB_Cross[%d]                          : %12.20f\n", temp.Inner_Rate_FB_Cross, i);
    fprintf(fptr, "Inner_Rate_FB_Roll[%d]                           : %12.20f\n", temp.Inner_Rate_FB_Roll, i);

    //IMU_Yaw
    fprintf(fptr, "IMU_Yaw[%d]                                      : %12.20f\n", temp.IMU_Yaw, i);
}
}

然后在主要内容我使用以下内容:

ARS_HR_LINE_1::ARS_HR_LINE_1_ALL* h;
ARS_HR_LINE_2::ARS_HR_LINE_2_ALL* h2;

h = ARS_HR_DEBUG_DATA.Process_HR_ARS_Line_1();
h2 = ARS_HR_DEBUG_DATA2.Process_HR_ARS_Line_2();

ARS_HR_DEBUG_DATA.Print_HR_Line_1(tassTxtFptr, i, h);
ARS_HR_DEBUG_DATA2.Print_HR_Line_2(tassTxtFptr, i, h2);

其中tassTxtFptr是指向文本文件的指针。

我的Process_HR_ARS_Line_1似乎工作正常,当我在visual studio中调出数组时,在返回之前,所有值看起来都是正确的。当我打印我的信息时,我得到了很多胡言乱语,混合了正确的价值观。知道我做错了吗?

5 个答案:

答案 0 :(得分:4)

Process函数结束时,数组h不再存在,所以指针指向它曾经的位置(谁知道现在有什么信息?)。我建议在main中声明数组并将其传递给要填充的函数,或使用其中一个STL容器,如vector

答案 1 :(得分:2)

您的声明ARS_HR_LINE_1::ARS_HR_LINE_1_ALL h[60];(一个局部变量)正在调用Process_HR_ARS_Line_1()的堆栈帧中为您的数组分配空间。程序离开该方法后,该堆栈上为该数组分配的内存不再有效。访问此内存是不确定的行为。

通过返回h,该数组衰减为指针,并且您实际上正在返回指向堆栈上无效内存空间的指针。

你如何解决这个问题?使用std::vector。或者,您可以使用new在堆上分配数组,但由于这是C ++,您应该使用可用的工具来简化内存管理。

答案 2 :(得分:1)

 ARS_HR_LINE_1::ARS_HR_LINE_1_ALL h[60];
 return h;

您正在返回指向局部变量的指针。当函数退出时它会被破坏。您应该使用new创建数组,并在使用后小心删除指针

答案 3 :(得分:1)

您正在堆栈上分配数组h。当您从函数返回时,h会离开作用域并从堆栈中释放。您返回一个指向h的指针,该指针不再有效!

使用new在函数外部存在的堆上分配空间(以后不要忘记delete!)或使用STL vector

答案 4 :(得分:1)

您正在堆栈中的方法内部分配数组,这意味着一旦您的方法完成它就会超出范围(这就是为什么它充满了carbage)。尝试在堆上分配它,或者如果你仍想在堆栈上分配它,请尝试使用call-by-reference。

可以通过更改代码来实现按引用调用:

void Process_HR_ARS_Line_1(ARS_HR_LINE_1_ALL* h);


你的主要现在看起来像这样:

ARS_HR_LINE_1::ARS_HR_LINE_1_ALL h[60];

ARS_HR_DEBUG_DATA.Process_HR_ARS_Line_1(&h);

ARS_HR_DEBUG_DATA.Print_HR_Line_1(tassTxtFptr, i, &h);


要在堆上分配列表,您可以执行以下操作(在堆上分配内容时,记住使用delete[]非常重要):

ARS_HR_LINE_1::ARS_HR_LINE_1_ALL* h = new ARS_HR_LINE_1::ARS_HR_LINE_1_ALL[60];

delete[] h;