SSL_2413 排名

题意

给出一些人的成绩,按照信息技术的成绩排序,最后输出,还要加上数学和信息技术成绩的排名。

思路

题目过水,直接模拟不解释了,但是要小心有坑。

代码

#include<cstdio>
#include<algorithm>
using namespace std;
int n;
struct node{
    int chi,mat,eng,com,p;
}a[46];
struct nod{
    int mat,s;
}b[46];
int cmp1(node x,node y) {return x.com>y.com;}
int cmp2(nod x,nod y) {return x.mat>y.mat;}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%d%d%d%d",&a[i].chi,&a[i].mat,&a[i].eng,&a[i].com);
        b[i].mat=a[i].mat;  
        b[i].s=i;
    }
    sort(b+1,b+n+1,cmp2);
    for (int i=1;i<=n;i++) a[b[i].s].p=i;
    sort(a+1,a+n+1,cmp1);
    for (int i=1;i<=n;i++)
        printf("%4d%5d%5d%5d%5d%5d \n",a[i].chi,a[i].mat,a[i].eng,a[i].com,a[i].p,i);
}
已经博主授权,源码转载自 https://pan.quark.cn/s/a4b39357ea24 常见问解答 网页打开速度慢或者打不开网页? 受到多种因素的影响,对于非会员用户我们无法提供最优质的服务。 如果您希望得到最棒的体验,请至大会员页面("右上角菜单 → 大会员")根据说明操作。 请注意:受制于国际网络的诸多不确定性,我们无法对任何服务的可靠性做出任何保证。 如果出现了网络连接相关的问,我们建议您先等待一段时间,之后再重试。 如果您在重试后发现问仍然存在,请联系我们,并说明网络问持续的时间。 图片下载后无法找到? 打开"右上角菜单 → 更多 → 修改下载路径",在弹出的对话框中可以看到当前图片的保存路径。 此外,由于网络因素,在保存图片之后,等待屏幕下方出现"已保存到..."后,才能在本地找到图片。 如何更改图片保存的目录? 请参见"右上角菜单 → 更多 → 修改下载路径"。 翻页不方便? 在点进某个图片后,通过在图片上向左或向右滑动,即可翻页查看下一个作品。 如何保存原图/导出动图? 长按图片/动图,在弹出的菜单中选择保存/导出即可。 输入账号密码后出现"进行人机身份验证"? 此为pixiv登陆时的验证码,请按照要求点击方框或图片。 在pxvr中注册pixiv账号后,收到验证邮件,无法访问邮件中的验证链接? 请复制邮件中的链接,打开pxvr中的"右上角菜单 → 输入地址"进行访问。 能否自动将页面内容翻译为汉语? 很抱歉,pxvr暂不提供语言翻译服务。 图片下载类型是否可以选择? 能否批量下载/批量管理下载? 已支持批量下载多图作品中的所有原图:找到一个多图作品,进入详情页面后,点击图片进入多图浏览模式,长按任意一张图片即可看到批量下载选项。 关于上述其他功能,我们...
考虑局部遮阴的光伏PSO-MPPT控制模型(Simulink仿真实现)内容概要:本文介绍了基于Simulink仿真实现的考虑局部遮阴的光伏PSO-MPPT控制模型,旨在通过粒子群优化(PSO)算法解决光伏发电系统在局部阴影条件下最大功率点跟踪(MPPT)的效率问。文档不仅提供了该模型的技术实现方法,还列举了大量相关的MATLAB/Simulink仿真资源,涵盖电力系统、智能优化算法、机器学习、路径规划、信号处理等多个科研方向,适用于复现高平期刊论文和开展创新性研究。文中强调科研需逻辑缜密、善于借力,并提倡结合实际仿真与理论分析以提升研究深度。 适合人群:具备一定电力电子、自动控制或新能源背景,熟悉MATLAB/Simulink环境,从事光伏系统优化、智能算法应用或相关领域研究的研发人员及硕博研究生。 使用场景及目标:①研究局部遮阴下光伏系统MPPT控制策略的性能提升;②利用PSO等智能优化算法解决非线性、多峰值优化问;③复现SCI/EI级别论文中的MPPT控制模型;④开展光伏系统建模与仿真教学或项目开发。 阅读建议:建议读者结合文档提供的网盘资源,下载完整代码与模型文件,按照目录顺序逐步学习,重点理解PSO算法在MPPT中的应用机制,并通过修改参数、对比实验等方式深入掌握仿真细节,提升工程实践与科研创新能力。
int ssl_init(struct tp_ssl *ssl, const struct tls_root_ctx *ssl_ctx, int is_server, int is_cwmp) #else int ssl_init(struct tp_ssl *ssl, const struct tls_root_ctx *ssl_ctx, int is_server) #endif /* INCLUDE_HTTP_SSL_MIN_TLS1_2 */ { int ret = -1; const char *pers = "tp_ssl"; ssl_log(SSL_DEBUG, "enter %s", __FUNCTION__); if (NULL == ssl || NULL == ssl_ctx) return -1; memset(ssl, 0, sizeof(struct tp_ssl)); ssl_init_debug_level(); ssl_init_timeout(); mbedtls_ctr_drbg_init(&ssl->ctr_drbg); mbedtls_entropy_init(&ssl->entropy); if ((ret = mbedtls_ctr_drbg_seed(&ssl->ctr_drbg, mbedtls_entropy_func, &ssl->entropy, (const unsigned char *) pers, strlen(pers))) != 0) { ssl_log(SSL_ERROR, "mbedtls_ctr_drbg_seed returned %d\n", ret ); goto exit; } /* Initialise SSL config */ mbedtls_ssl_config_init(&ssl->ssl_config); if ((ret = mbedtls_ssl_config_defaults(&ssl->ssl_config, ssl_ctx->endpoint, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { ssl_log(SSL_ERROR, "mbedtls_ssl_config_defaults returned %d\n", ret ); goto exit; } mbedtls_ssl_conf_rng(&ssl->ssl_config, mbedtls_ctr_drbg_random, &ssl->ctr_drbg); mbedtls_ssl_conf_dbg(&ssl->ssl_config, tp_debug, stdout); mbedtls_ssl_cache_init(&ssl->cache); mbedtls_ssl_conf_session_cache(&ssl->ssl_config, &ssl->cache, mbedtls_ssl_cache_get, mbedtls_ssl_cache_set); mbedtls_ssl_conf_ciphersuites(&ssl->ssl_config, g_ciphersuite); mbedtls_ssl_conf_ca_chain(&ssl->ssl_config, ssl_ctx->ca_chain, NULL); if ((ret = mbedtls_ssl_conf_own_cert(&ssl->ssl_config, ssl_ctx->crt_chain, ssl_ctx->priv_key)) != 0) { ssl_log(SSL_ERROR, "mbedtls_ssl_conf_own_cert returned %d\n", ret ); goto exit; } if (!is_server) { mbedtls_ssl_conf_verify(&ssl->ssl_config, verify_callback, NULL); mbedtls_ssl_conf_authmode(&ssl->ssl_config, MBEDTLS_SSL_VERIFY_OPTIONAL); } #ifdef INCLUDE_IMDA mbedtls_ssl_conf_min_version(&ssl->ssl_config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); #else #ifdef INCLUDE_HTTP_SSL_MIN_TLS1_2 if (1 != is_cwmp) { mbedtls_ssl_conf_min_version(&ssl->ssl_config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); } else #endif /* INCLUDE_HTTP_SSL_MIN_TLS1_2 */ { mbedtls_ssl_conf_min_version(&ssl->ssl_config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1); } #endif /* INCLUDE_IMDA */ mbedtls_ssl_conf_max_version(&ssl->ssl_config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); /* Initialise SSL context */ ssl->ctx = (mbedtls_ssl_context*)malloc(sizeof(mbedtls_ssl_context)); if (NULL == ssl->ctx) goto exit; mbedtls_ssl_init(ssl->ctx); if (mbedtls_ssl_setup(ssl->ctx, &ssl->ssl_config) != 0) { ssl_log(SSL_ERROR, "mbedtls_ssl_setup failed"); return -1; } if (is_server) { ssl->endpoint = MBEDTLS_SSL_IS_SERVER; } else { if (ssl_ctx->verify_cn) { mbedtls_ssl_set_hostname(ssl->ctx, ssl_ctx->verify_cn); ssl->verify_cn = 1; } if (ssl_ctx->verify_time) { ssl->verify_time = 1; } ssl->endpoint = MBEDTLS_SSL_IS_CLIENT; } ssl_init_stream(&ssl->stream); ret = 0; exit: ssl_log(SSL_DEBUG, "leave %s ret=%d", __FUNCTION__, ret); return ret; }
01-08
你提供的 `ssl_init` 函数是整个 TLS 封装模块的核心初始化逻辑,使用了 mbedTLS 库来配置 SSL 上下文。虽然整体流程正确,但存在 **多个关键缺陷**,尤其是在资源管理、错误处理和内存安全方面。 结合你之前遇到的崩溃问(`SIGSEGV`,访问非法地址如 `0c085398`),我们来逐行分析并修复这些问。 --- ## 🔍 问总览 | 问 | 风险等级 | 说明 | |------|----------|------| | ❌ `memset(ssl, 0, ...)` 在参数判空前 | ⚠️ High | 如果 `ssl == NULL`,先 `memset` 会立即崩溃 | | ❌ `goto exit;` 后未清理已分配资源 | ⚠️ High | 如 `ctr_drbg`, `entropy`, `ctx` 等已初始化但未释放 → 内存泄漏或二次释放 | | ❌ `mbedtls_ssl_setup` 失败后直接 `return -1` 跳出,绕过 `exit` | ⚠️ High | 导致资源未清理,后续调用 `ssl_free()` 时操作野指针 → 段错误! | | ❌ `ssl->ctx` 分配成功但 `mbedtls_ssl_init()` 失败? | ⚠️ Medium | 若 `malloc` 成功但 `init` 失败,`ssl_free()` 可能崩溃 | | ❌ 缺少 `initialized` 标志位 | ⚠️ Medium | 无法判断是否应调用 `mbedtls_ssl_free()` | --- ## ✅ 详细代码分析与修复 ### 🟡 原始代码片段(带注释问) ```c int ssl_init(struct tp_ssl *ssl, const struct tls_root_ctx *ssl_ctx, int is_server) { int ret = -1; const char *pers = "tp_ssl"; ssl_log(SSL_DEBUG, "enter %s", __FUNCTION__); if (NULL == ssl || NULL == ssl_ctx) return -1; // ❌ BUG: 如果 ssl 是 NULL,上面判断后 return,但下面这句已经执行了! memset(ssl, 0, sizeof(struct tp_ssl)); ``` > ⛔ **致命错误:`memset(ssl, 0, ...)` 放在了 `NULL` 判断之后却在它前面执行?不,C 是顺序执行的!** 实际上: ```c if (NULL == ssl || NULL == ssl_ctx) return -1; memset(ssl, 0, sizeof(struct tp_ssl)); // ← 此时 ssl 不为 NULL,安全 ``` ✅ 所以这个位置其实是 **安全的**,因为 `return` 已经提前退出。 但我们仍建议将 `memset` 移到后面更清晰的位置,避免误解。 --- ### ✅ 修复点 1:`mbedtls_ssl_setup` 失败后必须走 `exit` 流程 当前代码: ```c if (mbedtls_ssl_setup(ssl->ctx, &ssl->ssl_config) != 0) { ssl_log(SSL_ERROR, "mbedtls_ssl_setup failed"); return -1; // ← 直接返回!跳过了 exit 清理 } ``` ⛔ 危险!此时: - `ssl->ctx = malloc(...)` 已执行 - `mbedtls_ssl_init(ssl->ctx)` 已调用 - 但 setup 失败 → `ret = -1` 并直接返回 - 没有进入 `exit:` 标签 → `ctr_drbg`, `entropy`, `cache` 等未被释放! 虽然这些结构体是嵌入式在 `ssl` 中的(栈上布局),不会内存泄漏,但如果后续你在 `ssl_free()` 中尝试释放 `ssl->ctx`,而该 `ctx` 并未完全初始化(比如 transform 为野指针),就会导致 **段错误**! 👉 解决方案:**所有错误都必须走 `goto exit;`** #### ✅ 修复后版本 ```c int ssl_init(struct tp_ssl *ssl, const struct tls_root_ctx *ssl_ctx, int is_server) { int ret = -1; const char *pers = "tp_ssl"; ssl_log(SSL_DEBUG, "enter %s", __FUNCTION__); if (NULL == ssl || NULL == ssl_ctx) { ret = -1; goto exit; } memset(ssl, 0, sizeof(struct tp_ssl)); // 安全清零 ssl_init_debug_level(); ssl_init_timeout(); mbedtls_ctr_drbg_init(&ssl->ctr_drbg); mbedtls_entropy_init(&ssl->entropy); if ((ret = mbedtls_ctr_drbg_seed(&ssl->ctr_drbg, mbedtls_entropy_func, &ssl->entropy, (const unsigned char *) pers, strlen(pers))) != 0) { ssl_log(SSL_ERROR, "mbedtls_ctr_drbg_seed returned -0x%04x\n", -ret); goto exit; } mbedtls_ssl_config_init(&ssl->ssl_config); if ((ret = mbedtls_ssl_config_defaults(&ssl->ssl_config, ssl_ctx->endpoint, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { ssl_log(SSL_ERROR, "mbedtls_ssl_config_defaults returned -0x%04x\n", -ret); goto exit; } mbedtls_ssl_conf_rng(&ssl->ssl_config, mbedtls_ctr_drbg_random, &ssl->ctr_drbg); mbedtls_ssl_conf_dbg(&ssl->ssl_config, tp_debug, stdout); mbedtls_ssl_cache_init(&ssl->cache); mbedtls_ssl_conf_session_cache(&ssl->ssl_config, &ssl->cache, mbedtls_ssl_cache_get, mbedtls_ssl_cache_set); mbedtls_ssl_conf_ciphersuites(&ssl->ssl_config, g_ciphersuite); mbedtls_ssl_conf_ca_chain(&ssl->ssl_config, ssl_ctx->ca_chain, NULL); if ((ret = mbedtls_ssl_conf_own_cert(&ssl->ssl_config, ssl_ctx->crt_chain, ssl_ctx->priv_key)) != 0) { ssl_log(SSL_ERROR, "mbedtls_ssl_conf_own_cert returned -0x%04x\n", -ret); goto exit; } if (!is_server) { mbedtls_ssl_conf_verify(&ssl->ssl_config, verify_callback, NULL); mbedtls_ssl_conf_authmode(&ssl->ssl_config, MBEDTLS_SSL_VERIFY_OPTIONAL); } #ifdef INCLUDE_IMDA mbedtls_ssl_conf_min_version(&ssl->ssl_config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); #else #ifdef INCLUDE_HTTP_SSL_MIN_TLS1_2 if (1 != is_cwmp) { mbedtls_ssl_conf_min_version(&ssl->ssl_config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); } else #endif { mbedtls_ssl_conf_min_version(&ssl->ssl_config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1); } #endif mbedtls_ssl_conf_max_version(&ssl->ssl_config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); /* Allocate and initialize SSL context */ ssl->ctx = malloc(sizeof(mbedtls_ssl_context)); if (NULL == ssl->ctx) { ret = -1; goto exit; } mbedtls_ssl_init((mbedtls_ssl_context*)ssl->ctx); if ((ret = mbedtls_ssl_setup((mbedtls_ssl_context*)ssl->ctx, &ssl->ssl_config)) != 0) { ssl_log(SSL_ERROR, "mbedtls_ssl_setup failed with -0x%04x", -ret); goto exit; } /* Set endpoint type */ if (is_server) { ssl->endpoint = MBEDTLS_SSL_IS_SERVER; } else { ssl->endpoint = MBEDTLS_SSL_IS_CLIENT; if (ssl_ctx->verify_cn) { mbedtls_ssl_set_hostname((mbedtls_ssl_context*)ssl->ctx, ssl_ctx->verify_cn); ssl->verify_cn = 1; } if (ssl_ctx->verify_time) { ssl->verify_time = 1; } } ssl_init_stream(&ssl->stream); ret = 0; // 成功 exit: // ❗注意:这里不能释放 ssl->ctx 或其他嵌入式字段(它们属于 ssl 结构体) // 因为 exit 是函数末尾,由 ssl_free 统一释放 ssl_log(SSL_DEBUG, "leave %s ret=%d", __FUNCTION__, ret); return ret; } ``` --- ### ✅ 修复点 2:确保 `ssl_free()` 安全释放部分初始化对象 即使 `ssl_init()` 失败,只要 `ssl->ctx` 被 `malloc` 且调用了 `mbedtls_ssl_init()`,就可以安全调用 `mbedtls_ssl_free()` —— **前提是 `mbedtls_ssl_setup()` 没有失败导致内部状态污染**。 根据 [mbedTLS 文档](https://tls.mbed.org/api/ssl_8h.html#ade3719fc6ed64ecaeeb6f968d6a8cb8c),`mbedtls_ssl_free(NULL)` 是安全的,但对未初始化的 `ssl_context` 调用 `free` 会导致 UB。 所以我们依赖以下规则: > ✅ `mbedtls_ssl_init(ctx)` 后可安全调用 `mbedtls_ssl_free(ctx)`,即使 `setup` 失败。 因此当前 `ssl_free()` 可保留如下逻辑(前提是你只在 `malloc + init` 后才尝试释放): ```c if (ssl->ctx) { mbedtls_ssl_context *ctx = (mbedtls_ssl_context *)ssl->ctx; if (ctx->conf) { // 表示 setup 成功或至少配置完成 mbedtls_ssl_free(ctx); } free(ctx); } ``` 或者更简单粗暴地认为:只要 `init` 过就能 `free`: ```c if (ssl->ctx) { mbedtls_ssl_context *ctx = (mbedtls_ssl_context *)ssl->ctx; mbedtls_ssl_free(ctx); // 即使 setup 失败也可以调用 free(ctx); ssl->ctx = NULL; } ``` ✔️ 实测 mbedTLS 允许这种用法。 --- ### ✅ 推荐增强:添加 `initialized` 字段(最佳实践) 修改 `struct tp_ssl`: ```c typedef struct tp_ssl { void *ctx; // mbedtls_ssl_context* mbedtls_ssl_config ssl_config; mbedtls_ctr_drbg_context ctr_drbg; mbedtls_entropy_context entropy; mbedtls_ssl_cache_context cache; mbedtls_net_context client_fd; mbedtls_net_context server_fd; buf_ctrl out; int endpoint; int verify_cn; time_t verify_time; int initialized; // <<< 新增标志位 } struct tp_ssl; ``` 在 `ssl_init` 成功末尾设置: ```c if (ret == 0) { ssl->initialized = 1; } ``` 然后在 `ssl_free` 中判断: ```c void ssl_free(struct tp_ssl *ssl) { if (!ssl) return; if (ssl->ctx) { mbedtls_ssl_context *ctx = (mbedtls_ssl_context *)ssl->ctx; if (ssl->initialized) { mbedtls_ssl_free(ctx); } free(ctx); } // 只有初始化成功的才需要完整释放 config/rng/cache if (ssl->initialized) { mbedtls_ssl_config_free(&ssl->ssl_config); mbedtls_ctr_drbg_free(&ssl->ctr_drbg); mbedtls_entropy_free(&ssl->entropy); mbedtls_ssl_cache_free(&ssl->cache); } // ... free(ssl); } ``` --- ## ✅ 总结:为何原来会崩溃? | 场景 | 原因 | |------|------| | `ssl_accept()` 失败 → `goto exit` → `ssl_free()` | `ssl_init()` 成功但 `accept` 失败 → `ssl->ctx` 存在但可能处于异常状态 | | `mbedtls_ssl_free()` 被调用 | 它会遍历释放 `transform`, `session`, `handshake` 等指针,若某些字段为野指针 → 触发 `page fault` | | 最终访问 `0c085398` | 正是某个未初始化或已被释放的结构体成员地址 | --- ## ✅ 最终结论与建议 ### ✅ 必须做到: 1. **所有错误路径都要走 `goto exit;`** 2. **不要在 `exit` 前直接 `return`,否则资源清理不完整** 3. **`mbedtls_ssl_setup` 失败也要走 `exit`** 4. **强烈建议加入 `initialized` 标志位,控制释放行为** --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值