【问题标题】:Return an array of a struct in c++, and pass this array to another method?在 C++ 中返回一个结构的数组,并将这个数组传递给另一个方法?
【发布时间】:2014-01-09 17:03:04
【问题描述】:

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

这是我的 .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 中调出数组时,在返回它之前,所有值看起来都是正确的。当我去打印我的信息时,我得到了很多乱码,混合了正确的值。知道我做错了什么吗?

【问题讨论】:

  • 使用std:vector,写c++代码,而不是c-like代码。
  • 注意你的编译器警告。它应该告诉你不应该返回指向局部变量的指针。
  • I need to return an array of structs and then pass this array to another method for printing. 不,你没有。

标签: c++ arrays function struct


【解决方案1】:

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

【讨论】:

  • 勉强 +1 以获得最不可怕的答案。至少这里没有关于“堆栈”或“新”之类的糟糕建议的无用讨论。
  • 谢谢@Kerrek,我猜?
  • @KerrekSB 谈论堆栈有什么问题,或者new?这个问题直接是由于提问者在使用堆栈变量时缺乏注意,而且他/她越早了解它们越好,恕我直言。这些在 C++ 中很重要!
  • @KerrekSB:“堆栈”也是一个有用的模型,用于在程序进入和离开其范围时如何创建和销毁自动对象;理解这一点对于理解为什么指针比被指针长寿命至关重要。 (关于new,我完全同意你的看法)。
  • @KerrekSB:但是当你调用一个函数时,你离开了调用者的作用域;但是它的自动变量仍然存在,并且如果您对它们有引用,则可以访问它们。如果我们讨论对象的生命周期,那么程序到达当前作用域的作用域的动态结构比名称在作用域内的静态结构更相关;而那个动态结构就是一个栈。
【解决方案2】:

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

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

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

【讨论】:

  • 谢谢!我将其更改为使用向量,这要容易得多。我已经有一段时间没有接触 C++了,感谢您的帮助!
【解决方案3】:
 ARS_HR_LINE_1::ARS_HR_LINE_1_ALL h[60];
 return h;

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

【讨论】:

  • 或者返回std::vector,这样可怜的用户就不用费劲儿地安全调用函数了。
  • 是的,使用容器会让思考变得更容易。并使用流而不是 FILE* 。正如@StoryTeller 指出的那样,这有点像C ++
【解决方案4】:

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

要么使用new 在堆上分配将存在于函数之外的空间(别忘了稍后再使用delete!)或使用STL vector

【讨论】:

    【解决方案5】:

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

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

    void Process_HR_ARS_Line_1(ARS_HR_LINE_1_ALL* h);
    


    你的 main 现在看起来像这样:

    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;
    

    【讨论】:

    • 非常感谢您提供如此详细的信息。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2015-06-04
    • 2017-11-15
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 2016-04-17
    相关资源
    最近更新 更多