【问题标题】:Passing a pointer to a function causing the 2nd call to crash the program将指针传递给导致第二次调用使程序崩溃的函数
【发布时间】:2020-09-30 06:33:41
【问题描述】:

我正在测试一个压缩库,它对我来说工作正常,但我需要一个包装函数来避免一些不需要的参数。库调用如下所示:

typedef int WINAPI OodleLZ_CompressFunc(
        uint32_t codec, char *src_buf, uint64_t src_len, char *dst_buf, int64_t level,
        void *opts, int64_t offs);
typedef int WINAPI OodleLZ_DecompressFunc(
        char *src_buf, int64_t src_len, char *dst_buf, uint64_t dst_size, int fuzz, int crc, int verbose,
        uint8_t *dst_base, size_t e, void *cb, void *cb_ctx, void *scratch, size_t scratch_size, int threadPhase
    );

我分配的职能如下:

OodleLZ_CompressFunc* oodl_compress;
OodleLZ_DecompressFunc* oodl_decompress;

当我调用解压缩函数时,使用 oodl_compressoodl_decompress 的压缩函数一切正常。但是,当我为函数创建包装器时,压缩停止工作。

工作场景:

// Predefined data, compressed_size, decompressed_size
char *dec_data = new char [decompressed_size];
oodl_decompress(data, compressed_size, dec_data, decompressed_size, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);

char *com_data = new char [decompressed_size + 0x10000];
oodl_compress(c_type, dec_data, decompressed_size, com_data, c_level, 0, 0); //c_type and c_level are constants (7 in this case)

当我创建包装器Decompress 时,调用Decompress 有效,但调用oodl_compress 不再有效。 Decompress:

int Decompress(char* src_buf, int64_t src_len, char* dst_buf, uint64_t dst_len)
{
    oodl_decompress(src_buf, src_len, dst_buf, dst_len, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}

main.cpp:

// Predefined data, compressed_size, decompressed_size
char *dec_data = new char [decompressed_size];
Decompress(data, compressed_size, dec_data, decompressed_size);

char *com_data = new char [decompressed_size + 0x10000];
oodl_compress(c_type, dec_data, decompressed_size, com_data, c_level, 0, 0); //c_type and c_level are constants (7 in this case)

发生的情况是,在第二种情况下调用oodl_compress时,程序会冻结1秒钟然后退出,没有任何错误。之后我有代码将 fout<< 放入文件中,我可以看到在第二种情况下文件是空的,在第一种情况下文件被重新压缩,代表数据的原始状态。

我似乎不知道我的问题出在哪里,因为我只是将变量重新传递到另一个函数中,该函数只是用 0 填充剩余的参数,而不是将它放在 main 中。我知道这不是必需的,但了解这种情况下的问题将有助于我在未来避免这种情况。

【问题讨论】:

  • 我和你一起完全没有发现任何错误,但可能有一个更早的错误最终被函数暴露出来。
  • @user4581301 上一个代码是ifstream fin("file.bin", ios::binary); char data[100]; fin.read(data, 100);,下一个代码是ofstream fout("file.dec", ios::binary); for (int i = 0; i < decompressed_data; i++) fout<<dec_data[i];
  • 你在哪里(以及如何)将实际的函数地址分配给你的函数指针?
  • @AdrianMole 在一个名为 Oodle 的类中,在一个名为 resolve_functions() 的函数中。问题不在于函数分配,因为它在其他场景中工作。

标签: c++ c++11 pointers


【解决方案1】:

我发现了问题,但我不知道“为什么”是问题所在。

在我的解压功能中:

void Decompress(char* src_buf, int64_t src_len, char* dst_buf, uint64_t dst_len)
{
    int data_size = oodl_decompress(src_buf, src_len, dst_buf, dst_len, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);

    if (data_size < 0)
    {
        throw std::string("Decompression Error");
    }
}

在我的压缩函数中:

int64_t Compress(char *src_buf, uint64_t src_len, char* dst_buf)
{
    int64_t data_len;
    data_len = oodl_compress(compression_type, src_buf, src_len, dst_buf, compression_level, 0, 0);
    return data_len;
}

这两种情况的罪魁祸首都是data_lendata_size 变量。出于某种原因,每当我删除它们时,代码都可以正常工作。我猜这与堆栈/堆有关? (我不太擅长术语)。 对此的任何见解以及建议的修复/替代方案都将不胜感激! 现在我只是把这两个函数换成这样:

int64_t Compress(char *src_buf, uint64_t src_len, char* dst_buf)
{
    return oodl_compress(compression_type, src_buf, src_len, dst_buf, compression_level, 0, 0);
}

void Decompress(char* src_buf, int64_t src_len, char* dst_buf, uint64_t dst_len)
{
    oodl_decompress(src_buf, src_len, dst_buf, dst_len, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    • 2015-10-17
    • 1970-01-01
    相关资源
    最近更新 更多