Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在多线程应用程序中将数组作为函数返回传递_C++_Arrays_Multithreading - Fatal编程技术网

C++ 在多线程应用程序中将数组作为函数返回传递

C++ 在多线程应用程序中将数组作为函数返回传递,c++,arrays,multithreading,C++,Arrays,Multithreading,我尝试生成多线程的代码,在特定步骤中,我必须检索在堆上生成的数组。 这是代码: 下面的函数将调用另一个名为read_bi5_to_bin的函数,它将传递给它初始化为nullptr data_bin_buffer的unsigned char* int HTTPRequest::read_bi5_main(boost::filesystem::path p, ptime epoch) { boost::unique_lock<boost::mutex> read_bi5_to_

我尝试生成多线程的代码,在特定步骤中,我必须检索在堆上生成的数组。
这是代码:
下面的函数将调用另一个名为read_bi5_to_bin的函数,它将传递给它初始化为nullptr data_bin_buffer的unsigned char*

 int HTTPRequest::read_bi5_main(boost::filesystem::path p, ptime epoch)
{
    boost::unique_lock<boost::mutex> read_bi5_to_bin_lock(m_read_bi5_to_binMutex,boost::defer_lock);

    unsigned char *buffer;
    size_t buffer_size;

    int counter;

    size_t raw_size = 0;

    std::string filename_string = p.generic_string();
    path p2 = p;
    p2.replace_extension(".bin");
    std::string filename_string_2_bin =p2.generic_string() ;

    path p3 = p;
    p3.replace_extension(".csv");
    std::string filename_string_2_csv = p3.generic_string();

    const char *filename = filename_string.c_str();
    const char *filename_2_bin = filename_string_2_bin.c_str();

    const char *filename_2_csv = filename_string_2_csv.c_str();

    if (fs::exists(p) && fs::is_regular(p)) 
    {
        buffer_size = fs::file_size(p);
        buffer = new unsigned char[buffer_size];
    }
    else {
        //??5-17-2020 isolate multithreaded error
        read_bi5_to_bin_lock.lock();
        BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) << "Error: couldn't access the data file. |"
            << filename << "|" << std::endl;
        read_bi5_to_bin_lock.unlock();

        return 2;
    }

    std::ifstream fin(filename, std::ifstream::binary);
    //fin.open(filename, std::ifstream::binary);
    fin.read(reinterpret_cast<char*>(buffer), buffer_size);
    fin.close();

    //5-11-2020 the next line will be commented and put in HTTPCLIent constructor
    //mHTTPRequest_Symbol_str= mHTTPRequest_HTTPClient_shared_pointer->Get_mHttpClient_HttpSymbolPrepareGet_shared_pointer()->mSymbol_strGet() ;
    std::size_t pos = mHTTPRequest_Symbol_str.find("JPY");// position of "h_ticks.bi5" in str
    double PV;
    if (pos != std::string::npos)
    {
        PV = PV_YEN_PAIR;
    }
    else
    {
        PV = PV_DOLLAR_PAIR;
    }
    //??5-17-2020 isolate multithreaded error
    read_bi5_to_bin_lock.lock();
    //5-20-2020
    //boost::shared_ptr<unsigned char> data_bin_buffer = boost::make_shared<unsigned char>() ;
    //n47::tick_data *data = n47::read_bi5_to_bin(
    //  buffer, buffer_size, epoch, PV, &raw_size, data_bin_buffer.get());
    unsigned char* data_bin_buffer = nullptr;
    n47::tick_data *data = n47::read_bi5_to_bin(
            buffer, buffer_size, epoch, PV, &raw_size, data_bin_buffer);
    //5-11-2020 here i will save binary file
    //boost::unique_lock<boost::mutex> read_bi5_to_bin_lock(m_read_bi5_to_binMutex);
    std::string file_name_path_string=output_compressed_file_2(data_bin_buffer, raw_size, filename_2_bin);
    read_bi5_to_bin_lock.unlock();

    path file_name_path_2{ file_name_path_string }; 
    buffer_size = 0;    
    if (fs::exists(file_name_path_2) && fs::is_regular(file_name_path_2)) 
    {
        //??5-17-2020 isolate multithreaded error
        read_bi5_to_bin_lock.lock();

        BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) << boost::this_thread::get_id() <<"\t we can access the data .bin file. |"
            << filename_2_bin << "| with size ="<< fs::file_size(file_name_path_2) << std::endl;
        read_bi5_to_bin_lock.unlock();

    }
    else {
        //??5-17-2020 isolate multithreaded error
        read_bi5_to_bin_lock.lock();

        BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) << "Error: couldn't access the data .bin file. |"
            << filename_2_bin << "|" << std::endl;
        read_bi5_to_bin_lock.unlock();

        return 2;
    }

    n47::tick_data_iterator iter;

    //5-11-2020 here i will save file.csv from data which is pointer to vector to pointers to ticks

    if (data == 0) {
        //??5-17-2020 isolate multithreaded error
        read_bi5_to_bin_lock.lock();

        BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) << "Failure: Failed to load the data!" << std::endl;
        read_bi5_to_bin_lock.unlock();

        //5-14-2020 file is empty
        //return 0;
    }
    //5-15-2020 take care that without else ,error happens with empty files because data is pointer to vector of pointers to ticks .so when data is made inside read_bi5 ,it is made as null pointer and later it is assigned to vector if file has ticks.if file does not have ticks ,then it is just returned as null pointer .so when dereferencing null pointer we got error
    else if (data->size() != (raw_size / n47::ROW_SIZE)) {
        //??5-17-2020 isolate multithreaded error
        read_bi5_to_bin_lock.lock();

        BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) << "Failure: Loaded " << data->size()
            << " ticks but file size indicates we should have loaded "
            << (raw_size / n47::ROW_SIZE) << std::endl;
        read_bi5_to_bin_lock.unlock();

        //5-14-2020 file is empty
        //return 0;
    }

    //??5-17-2020 isolate multithreaded error
    read_bi5_to_bin_lock.lock();

    BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) << "time, bid, bid_vol, ask, ask_vol" << std::endl;
    read_bi5_to_bin_lock.unlock();

    counter = 0;
    std::ofstream out_csv(filename_string_2_csv);
    if (data == 0)
    {

    }
    else if (data != 0)
    {
        ////read_bi5_to_bin_lock.lock();

        for (iter = data->begin(); iter != data->end(); iter++) {
            //5-11-2020 here i will save file.csv from data which is pointer to vector to pointers to ticks>>>>>>>here i should open file stream for output and save data to it
            out_csv << ((*iter)->epoch + (*iter)->td) << ", "
                << (*iter)->bid << ", " << (*iter)->bidv << ", "
                << (*iter)->ask << ", " << (*iter)->askv << std::endl;
            //??5-17-2020 isolate multithreaded error
            read_bi5_to_bin_lock.lock();

            BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) <<
                boost::this_thread::get_id() << "\t"<<((*iter)->epoch + (*iter)->td) << ", "
                << (*iter)->bid << ", " << (*iter)->bidv << ", "
                << (*iter)->ask << ", " << (*iter)->askv << std::endl;
            read_bi5_to_bin_lock.unlock();

            counter++;
        }
        ////read_bi5_to_bin_lock.unlock();

    }
    out_csv.close();
    //5-13-2020

    //??5-17-2020 isolate multithreaded error
    read_bi5_to_bin_lock.lock();

    BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) << ".end." << std::endl << std::endl
        << "From " << raw_size << " bytes we read " << counter
        << " records." << std::endl
        << raw_size << " / " << n47::ROW_SIZE << " = "
        << (raw_size / n47::ROW_SIZE) << std::endl;
    read_bi5_to_bin_lock.unlock();


    delete data;
    delete[] buffer;    
    delete [] data_bin_buffer;
    return 0;
}
然后在n47::lzma::decompress内部,将在堆上生成一个名为Exputffer的数组。我需要在data\u bin\u buffer的read\u bi5\u main中检索此缓冲区
这是n47::lzma::解压缩的代码

unsigned char *decompress(
        unsigned char *inBuffer, size_t inSize, int *status, size_t *outSize) {
    unsigned char *outBuffer = 0;
    elzma_file_format format = ELZMA_lzma;

    elzma_decompress_handle handle;
    handle = elzma_decompress_alloc();

    if (handle == 0) {
        *status = -1;
    } else {
        // decompression...
        datastream ds(inBuffer, inSize);
        *status = elzma_decompress_run(
            handle,
            inputCallback, static_cast<void*>(&ds),
            outputCallback, static_cast <void*>(&ds),
            format);

        if (*status == ELZMA_E_OK) {
            *outSize = ds.outData.size();
            outBuffer = new unsigned char[ ds.outData.size() ];
            std::copy(ds.outData.begin(), ds.outData.end(), outBuffer);
        }
        elzma_decompress_free(&handle);
    }

    return outBuffer;
}
无符号字符*解压缩(
未签名字符*inBuffer,大小inSize,int*状态,大小超大号){
无符号字符*exputffer=0;
elzma_文件格式=elzma_lzma;
elzma_减压_手柄;
handle=elzma_decompress_alloc();
如果(句柄==0){
*状态=-1;
}否则{
//解压。。。
数据流ds(inBuffer、inSize);
*状态=elzma\u解压缩\u运行(
手柄
inputCallback、静态转换(&ds),
outputCallback、静态转换(&ds),
格式);
如果(*状态==ELZMA_E_OK){
*outSize=ds.outData.size();
exputffer=新的无符号字符[ds.outData.size()];
std::copy(ds.outData.begin(),ds.outData.end(),exputffer);
}
elzma_解压_释放(&handle);
}
返回爆发器;
}

当我运行这个程序时,它会出现错误。这里有一个非常有用的程序告诉我,问题出在数据缓冲区,因为它只有一个字节。它建议我避免使用共享指针。当我将它转换为普通指针时,如果将它初始化为nullptr,它会出现另一个错误。我是否应该不初始化指针

您的
读取bi5到bin
代码已损坏

tick_data* read_bi5_to_bin(
    unsigned char *lzma_buffer, size_t lzma_buffer_size, pt::ptime epoch,
    float point_value, size_t *bytes_read, unsigned char* buffer_decompressed) {
    tick_data *result = 0;
代码接收一个名为
buffer\u decompressed
的指针

    // decompress
    int status;
    buffer_decompressed = n47::lzma::decompress(lzma_buffer,
        lzma_buffer_size, &status, bytes_read);
然后它扔掉它收到的值,并得到一些其他值

    if (status != N47_E_OK) 
    {
        bytes_read = 0;
    }
    else {
        // convert to tick data (with read_bin).
        result = read_bin(buffer_decompressed, *bytes_read, epoch, point_value);
        //delete[] buffer;
    }

    return result;
}
而且它从不返回或释放它存储在
缓冲区中的值

    // decompress
    int status;
    buffer_decompressed = n47::lzma::decompress(lzma_buffer,
        lzma_buffer_size, &status, bytes_read);

哦。

我在代码中发现了问题。
这是我传递指向未签名字符的指针以将\u bi5\u读取到\u bin的方式。
起初,我认为传递指针变量是正确的,“就像传递左值引用一样”,但我错了很多。引用与指针不同。
指针变量是指针类型的左值变量。因此,它被复制到函数中,并在函数中生成新的左值变量。新变量具有与传递的指针相同的值。该值是数组中第一个无符号字符的地址。
但我真正需要的是将指针传递给指向无符号字符的指针。然后,指向指针的指针将被复制到函数中。复制变量的值将是指向无符号字符的指针的地址。这就是我需要从函数中检索的内容。
我使用&运算符获取指向指针的指针。然后我阅读了非常有用的注释,建议使用**,因此我将代码改为使用**。瞧,它可以工作
这是修改后的代码:

read_bi5_to_bin_lock2.lock();
    //5-20-2020
    //boost::shared_ptr<unsigned char> data_bin_buffer = boost::make_shared<unsigned char>() ;
    //n47::tick_data *data = n47::read_bi5_to_bin(
    //  buffer, buffer_size, epoch, PV, &raw_size, data_bin_buffer.get());
    unsigned char *data_bin_buffer = 0 ;
    n47::tick_data *data = n47::read_bi5_to_bin(
            buffer, buffer_size, epoch, PV, &raw_size, &data_bin_buffer);
    //5-11-2020 here i will save binary file
    //boost::unique_lock<boost::mutex> read_bi5_to_bin_lock(m_read_bi5_to_binMutex);
    std::string file_name_path_string=output_compressed_file_2(&data_bin_buffer, raw_size, filename_2_bin);
    read_bi5_to_bin_lock2.unlock();

非常感谢戴维施瓦茨的有益评论

这个问题中有太多不相关的代码。当问题描述只是“ItGivesError”时,我们甚至没有完整的代码(因此我们自己无法运行它来查看错误),几乎不可能帮助您。如果您的问题是关于代码中的错误,请提供复制错误的完整代码。如果这是一个一般性的“我该怎么做”问题,请只给我们最少的代码,让我们清楚地看到情况,而不需要不相关的代码。您有
delete[]data\u bin\u buffer。当且仅当
data\u bin\u buffer
分配了
new[]
时,这才合适。但是我们看不到分配了
数据\u bin\u缓冲区的代码。所以我们无法知道这是否正确。@DavidSchwartz data_bin_buffer在read_bi5_main中作为buffer_在read_bi5_to_bin中解压缩,最终被分配给n47::lzma::decompressI中的Exputfer。我不知道什么是
read_bi5_to_bin
。谷歌搜索什么也没找到。如果您的问题是关于如何使用该代码,我们需要查看该代码或至少其文档。如果您的问题是一般性的“我应该如何最好地做到这一点”,请不要提及我们看不到的实施细节。要理解这段代码,我需要知道的第一件事是
data\u bin\u buffer
是否用
new[]
或其他方式分配。否则,我无法判断您对
delete[]
的呼叫是否正确。(为什么使用
delete[]
?文档中有没有提到?这是猜测?@DavidSchwartz该代码包含在问题中??)??!!!这是第二个函数是的,这是因为我想返回两个东西:勾选数据*和字节数组。。。所以我让函数返回tick_data*,然后我将指针作为参数传递给它,然后将指针分配给数组…问题是传递的指针被复制到函数中…所以任何更改都发生在副本上,而不是传递的指针…我希望传递的指针被分配给数组,而不是它的副本…我对数据进行了更改unsigned_char值,我使用&operator获取它的地址,并将此&data_bin_缓冲区作为参数传递给函数。它一直工作,直到我尝试删除它,然后崩溃。您是否修复了我上面描述的错误?我们能看看你认为应该有效的代码吗?如果要通过作为参数传递的指针返回
无符号字符*
,则该参数必须是
无符号字符**
。您还没有解释为什么认为
delete[]
是释放缓冲区的合适方法。这是猜测吗?我使用delete[]是因为指针被分配给exputfer,它是lzma::decompress堆上的缓冲区。所以我不仅要删除指针,还要删除它的数组。@ahmedallam这是无效的推理。如果您知道缓冲区是用
new[]
@ahmedallam分配的,则只应使用
delete[]
<
tick_data* read_bi5_to_bin(
    unsigned char *lzma_buffer, size_t lzma_buffer_size, pt::ptime epoch,
    float point_value, size_t *bytes_read, unsigned char** buffer_decompressed) {
    tick_data *result = 0;

    // decompress
    int status;
    *buffer_decompressed = n47::lzma::decompress(lzma_buffer,
        lzma_buffer_size, &status, bytes_read);