Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

未分配内存的指针被释放异常 #3055

Open
zhuzhu18 opened this issue Oct 21, 2024 · 1 comment
Open

未分配内存的指针被释放异常 #3055

zhuzhu18 opened this issue Oct 21, 2024 · 1 comment
Labels
question Further information is requested

Comments

@zhuzhu18
Copy link

zhuzhu18 commented Oct 21, 2024

平台(如果交叉编译请再附上交叉编译目标平台):

Platform(Include target platform as well if cross-compiling):

mac os 11.7.10

代码如下:

C++
//
// Created by xxx on 19.9.24.
//

#include<MNN/Interpreter.hpp>
#include<MNN/ImageProcess.hpp>
#include<MNN/expr/Expr.hpp>
#include<MNN/expr/Executor.hpp>
#include<MNN/expr/ExprCreator.hpp>
#include<MNN/expr/Module.hpp>
#include<MNN/AutoTime.hpp>
#include
#include
#include
#include
#include

class SESR{
public:
SESR()=default;
int Init(const char* model_path);
std::vectorMNN::Express::VARP pre_process(const uint8_t * yuv_data, int width, int height, int channels);
std::vectorMNN::Express::VARP& processing(std::vectorMNN::Express::VARP& yuv_var);
uint8_t* post_process(std::vectorMNN::Express::VARP& yuv_var);

private:
const float mean_vals[1] = {0.f};
const float normal_vals[1] = {1.f/255};
std::shared_ptrMNN::CV::ImageProcess pretreat;
std::shared_ptrMNN::Express::Module net = nullptr;
};

int SESR::Init(const char* model_path) {
net.reset(MNN::Express::Module::load(std::vectorstd::string{"img"}, std::vectorstd::string{"out"}, model_path));
if(nullptr == net){
MNN_ERROR("load model failed!\n");
}
MNN::ScheduleConfig sConfig;
// sConfig.type = MNN_FORWARD_CPU;
sConfig.type = MNN_FORWARD_OPENCL;
sConfig.backupType = MNN_FORWARD_VULKAN;
sConfig.numThread = std::thread::hardware_concurrency(); // cpu推理时的线程数
MNN::BackendConfig backendConfig;
backendConfig.memory = MNN::BackendConfig::Memory_Normal;
backendConfig.precision = MNN::BackendConfig::Precision_Normal;
sConfig.backendConfig = &backendConfig;

// std::shared_ptrMNN::Express::Executor::RuntimeManager rtmgr{
// MNN::Express::Executor::RuntimeManager::createRuntimeManager(sConfig)
// };
// if(nullptr == rtmgr){
// MNN_ERROR("Empty RuntimeManager\n");
// }
MNN::CV::ImageProcess::Config config;
config.sourceFormat = MNN::CV::YUV_I420; // 指定源格式YUV_I420
config.destFormat = MNN::CV::YUV_I420; // 转换成的目标格式YUV_I420
std::memcpy(config.mean, mean_vals, sizeof(mean_vals));
std::memcpy(config.normal, normal_vals, sizeof(normal_vals));
pretreat = std::shared_ptrMNN::CV::ImageProcess{MNN::CV::ImageProcess::create(config)};
}

std::vectorMNN::Express::VARP SESR::pre_process(const uint8_t* yuv_data, int width, int height, int channels) {
// MNN::Express::Variable::Info y_info{MNN::Express::NCHW, {1, channels, height, width},
// halide_type_of(), channelsheightwidth};
// MNN::Express::EXPRP y_expr = MNN::Express::Expr::create(std::move(y_info), yuv_data, MNN::Express::VARP::INPUT, MNN::Express::Expr::REF);
// MNN::Express::VARP y = MNN::Express::Variable::create(y_expr);
MNN::Express::VARP y = MNN::Express::_Input({1, channels, height, width}, MNN::Express::NCHW); // 模型输入格式NCHW, RGB
pretreat->convert(yuv_data, width, height, widthchannels, y->writeMap(),
width, height, channels, width
channels, halide_type_of()); // y通道数据

MNN::Express::Variable::Info u_info{MNN::Express::NCHW, {1, channels, height/2, width/2},
                                    halide_type_of<uint8_t>(), channels*height*width/4};
MNN::Express::EXPRP u_expr = MNN::Express::Expr::create(std::move(u_info), yuv_data+channels*height*width, MNN::Express::VARP::INPUT, MNN::Express::Expr::REF);
MNN::Express::VARP u = MNN::Express::Variable::create(u_expr);       // u通道数据

MNN::Express::Variable::Info v_info{MNN::Express::NCHW, {1, channels, height/2, width/2},
                                    halide_type_of<uint8_t>(), channels*height*width/4};
MNN::Express::EXPRP v_expr = MNN::Express::Expr::create(std::move(v_info), yuv_data+channels*height*width*5/4, MNN::Express::VARP::INPUT, MNN::Express::Expr::REF);
MNN::Express::VARP v = MNN::Express::Variable::create(v_expr);       // v通道数据
y = y * MNN::Express::_Scalar<float>(1.f/255);
std::vector<MNN::Express::VARP> yuv_var = {y, u, v};
return yuv_var;

}

std::vectorMNN::Express::VARP& SESR::processing(std::vectorMNN::Express::VARP& yuv_var) {
yuv_var[0] = net->onForward({yuv_var[0]})[0]; // 取出第一个输出
yuv_var[1] = MNN::Express::_Resize(yuv_var[1], 1.5, 1.5); // 对u通道数据插值缩放
yuv_var[2] = MNN::Express::_Resize(yuv_var[2], 1.5, 1.5); // 对v通道数据插值缩放

return yuv_var;

}

uint8_t* SESR::post_process(std::vectorMNN::Express::VARP& yuv_var) {
yuv_var[0] = MNN::Express::_Relu6(yuv_var[0], 0.0f, 1.0f); // 截断到[0, 255]
yuv_var[0] = yuv_var[0] * MNN::Express::_Scalar(255.0f); // 像素值缩放到[0, 255]之间
yuv_var[0] = MNN::Express::_Cast<uint8_t>(yuv_var[0]); // 像素值转换为整数
yuv_var[0] = MNN::Express::_Reshape(yuv_var[0], {-1});
yuv_var[1] = MNN::Express::_Reshape(yuv_var[1], {-1});
yuv_var[2] = MNN::Express::_Reshape(yuv_var[2], {-1});

MNN::Express::VARP out_var = MNN::Express::_Concat(yuv_var, 0);
auto* out_img = out_var->readMap<uint8_t>();

return const_cast<uint8_t*>(out_img);

}

int main(){
const std::string& file_path = "/Users/xxx/pycharm_projects/mnn_practice/720p_I420.yuv";
const std::string& dest_path = "/Users/xxx/pycharm_projects/mnn_practice/out_720p.yuv";
const std::string& model_path = "/Users/xxx/pycharm_projects/mnn_practice/sesr_c1.mnn";
u_int32_t width = 1280;
u_int32_t height = 720;
u_int32_t channels = 1;
u_int32_t num_pixels = width * height * channels * 1.5; // 每个像素有3个通道(R, G, B)

// 分配内存来存储RGB数据
uint8_t* yuv_data = new uint8_t[num_pixels];

// 打开文件
std::ifstream file(file_path, std::ios::binary);
if (!file.is_open()) {
    std::cerr << "读取文件数据失败: " << file_path << std::endl;
    delete[] yuv_data;
    return 1;
}
// 读取数据到内存
file.read(reinterpret_cast<char*>(yuv_data), num_pixels);
file.close();

std::shared_ptr<SESR> model {new SESR()};
model->Init(model_path.c_str());        // 加载模型文件, 设置cpu/gpu/npu推理, 线程数等

std::vector<MNN::Express::VARP> yuv_var = model->pre_process(yuv_data, width, height, channels);      // 从连续内存的数组中读取yuv三个通道的数据写入相应的VARP中, 并放入一个vector中

yuv_var = model->processing(yuv_var);     // y通道通过模型超分, u和v通道直接插值

uint8_t* out_img = model->post_process(yuv_var);     // 输出截断至[0, 255], 并取整, RGB->BGR
// 打开文件写入
std::ofstream outFile(dest_path, std::ios::binary | std::ios::out);
if (!outFile.is_open()) {
    std::cerr << "无法创建文件: " << dest_path << std::endl;
    return 1;
}
num_pixels = yuv_var[0]->getInfo()->size + yuv_var[1]->getInfo()->size + yuv_var[2]->getInfo()->size;   // yuv三个通道的总像素个数
// 写入 yuv 数据
outFile.write(reinterpret_cast<char*>(out_img), num_pixels);

outFile.close();
delete[] yuv_data;

return 0;

}

报的异常截图如下:

52AFBA22-F07F-4033-85C2-C96746EEFC27

模型文件:https://github.com/zhuzhu18/sesr/blob/main/sesr_c1.mnn

@jxt1234
Copy link
Collaborator

jxt1234 commented Oct 22, 2024

可以先用 Xcode 开 asan 测试一下

@jxt1234 jxt1234 added the question Further information is requested label Oct 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants