2014-01-09 39 views
-1

我需要返回一個結構數組,然後將這個數組傳遞給另一個打印方法。在C++中返回一個結構數組,並將該數組傳遞給另一個方法?

這裏是我的.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中調出數組之前,在返回它之前,所有的值看起來都是正確的。當我去打印我的信息時,我收到了很多亂碼,混合了正確的值。任何想法我做錯了什麼?

+1

使用'std:vector',編寫'C++'代碼,而不是'c'類代碼。 – StoryTeller

+1

注意你的編譯器警告。它應該告訴你,你不應該返回一個指向局部變量的指針。 –

+1

'我需要返回一個結構數組,然後將這個數組傳遞給另一種打印方法。「不,你不知道。 –

回答

2

您的聲明ARS_HR_LINE_1::ARS_HR_LINE_1_ALL h[60];(局部變量)正在爲您的陣列在調用Process_HR_ARS_Line_1()的調用的堆棧幀內分配空間。在程序離開該方法後,爲該陣列分配的堆棧內存不再有效。訪問這個內存是未定義的行爲。

通過返回h,該數組衰減到一個指針,並且您實際上正在返回指向堆棧上無效內存空間的指針。

你如何解決這個問題?使用std::vector。或者,您可以使用new在堆上分配陣列,但由於這是C++,因此應該使用可用的設施來簡化內存管理。

+1

謝謝!我將它改爲使用矢量,它非常容易。我在一段時間內沒有碰過C++,所以我感謝你的幫助! – shawleigh17

4

Process函數結束時數組h不復存在,所以指針指向它以前的位置(並且誰知道現在有什麼信息?)。我會建議在main中聲明數組並將其傳遞給要填充的函數,或者使用其中一個STL容器,如vector

+1

最不好的答案勉強+1。至少在這裏沒有無用的談論「堆疊」或可怕的建議,如「新」。 –

+1

謝謝,@Kerrek,我猜? – tabstop

+1

@KerrekSB談論堆棧或'new'有什麼問題?這個問題直接歸因於提問者在使用堆棧變量時缺乏照顧,並且他/她越早了解他們越好,恕我直言。這些在C++中很重要! – Keeler

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

您正在返回一個指向局部變量的指針。它在函數退出時被破壞。您應該使用新建陣列,並在使用後注意刪除指針

+2

或者返回'std :: vector',這樣窮人用戶就不必跳過箍環來安全地調用函數。 –

+0

是的,使用容器會使認爲更容易。並使用流而不是FILE *。正如@StoryTeller所指出的,這有點像C++ C++ –

1

您正在分配堆棧上的陣列h。從函數返回時,h將離開作用域,並從堆棧中釋放。你返回一個指向h的指針,它不再有效!

要麼使用new來分配存在於函數之外的堆上的空間(不要忘記以後要用delete!)或使用STL vector

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; 
+0

非常感謝您如此詳細。我感謝您的幫助! – shawleigh17

相關問題