2014-03-19 50 views
2

我有一個信號發出一個std::vector<uint8_t>其中包含一個數據的負載(一個緩衝區)。從Qt的槽功能中修改參數是否安全?

然後在接收對象我有一個狹槽,它接受一個參數std::vector<uint8_t> data

然後我嘗試將此數據進行解碼。其中一件事我必須做的是去除填充,例如:

void receive_slot(std::vector<uint8_t> data) 
{ 
    // Remove padding 
    if (data.size() > 20) 
     data.resize(data.size() - 20); 
} 

現在,我認爲這種說法傳入是一個副本,我可以「做什麼,我想」。但是,做一個大於10字節的重新大小會使我的程序崩潰。我認爲重新調整大小不超過10個字節不會因運氣而崩潰。

因此,我認爲我不能安全地做到這一點,應該首先將它複製到新的數據緩衝區。

任何人都可以啓發我關於此?

+0

你能否精確一點,當它崩潰時究竟發生了什麼?你有什麼信息嗎? – JBL

+0

還有更多的事情要做,但這裏是來自Windows的消息:'程序意外完成。 C:\ local \ projects \ Qt \ Audio \ build-AudioTest-Desktop_Qt_5_2_1_MSVC2010_32bit-Debug \ debug \ AudioTest.exe崩潰了' –

+0

這很薄,你是否執行了其他操作?因爲目前看來完全沒問題。 – JBL

回答

4

爲了提供一個直接anwser的問題:在Qt的

插槽都只是正常的函數調用時(和與它們被稱爲參數的區別,通過Qt的管理),它是完全有效的修改函數參數(當非const顯然)。當你說你得到了一份副本,並且你可以「做你想做的事」時,你是對的。

在這種情況下,錯誤並不完全來自您修改函數參數的事實。

+0

謝謝你,這解決了問題:) +1 –

2

您顯示的代碼是完全有效和安全的,並且問題在代碼中的其他地方。還有一些東西正在破壞內存,並且偶然發生在receive_slot中的崩潰。要驗證這一點非常簡單:在SO上提出問題之前,您應該先將下面的最小測試用例放在一起。

適合我。

#include <vector> 
#include <QObject> 
#include <QCoreApplication> 
#include <QAtomicInt> 

QAtomicInt n = 0; 

class Object : public QObject { 
    Q_OBJECT 
public: 
    Q_SIGNAL void source(const std::vector<uint8_t> &); 
    Q_SLOT void sink(std::vector<uint8_t> data) { 
     // Remove padding 
     if (data.size() > 20) 
     data.resize(data.size() - 20); 
     n.fetchAndAddOrdered(1); 
    } 
}; 
Q_DECLARE_METATYPE(std::vector<uint8_t>) 

int main(int argc, char ** argv) 
{ 
    QCoreApplication a(argc, argv); 
    qRegisterMetaType<std::vector<uint8_t> >(); 
    Object src, dstD, dstQ; 
    const int N = 1000000; 
    // note elision of const & from the parameter types 
    dstD.connect(&src, SIGNAL(source(std::vector<uint8_t>)), 
       SLOT(sink(std::vector<uint8_t>))); 
    dstQ.connect(&src, SIGNAL(source(std::vector<uint8_t>)), 
       SLOT(sink(std::vector<uint8_t>)), Qt::QueuedConnection); 
    for (int i = 0; i < N; ++i) { 
     std::vector<uint8_t> v; 
     v.resize(qrand() % 100); 
     emit src.source(v); 
    } 
    a.processEvents(); 
    Q_ASSERT(n.loadAcquire() == (2*N)); 
    return 0; 
} 

#include "main.moc" 
+0

感謝您的回答和意見,引導我在正確的方向+1 –