在 c++ 中返回一个结构数组,并将此数组传递给另一个方法

Return an array of a struct in c++, and pass this array to another method?

本文关键字:数组 方法 另一个 结构 返回 c++ 一个      更新时间:2023-10-16

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

这是我的.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]                                      : %un", temp.Counter, i);
    //Rate FB
    fprintf(fptr, "Inner_Rate_FB_Fine[%d]                           : %12.20fn", temp.Inner_Rate_FB_Fine, i);
    fprintf(fptr, "Inner_Rate_FB_Cross[%d]                          : %12.20fn", temp.Inner_Rate_FB_Cross, i);
    fprintf(fptr, "Inner_Rate_FB_Roll[%d]                           : %12.20fn", temp.Inner_Rate_FB_Roll, i);
    //IMU_Yaw
    fprintf(fptr, "IMU_Yaw[%d]                                      : %12.20fn", 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 中调出数组时,在返回它之前,所有值看起来都正确。当我去打印我的信息时,我得到很多胡言乱语,混合了正确的值。知道我做错了什么吗?

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

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

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

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

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

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

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

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

你在堆栈上分配方法内的数组,这意味着一旦你的方法完成,它就会超出范围(这就是为什么它充满了碳水化合物)。尝试改为在堆上分配它,或者如果您仍想在堆栈上分配它,请尝试使用按引用调用。

可以通过更改代码来实现按引用调用,如下所示:

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;