[C语言]实现一个 int cal(int *array,int n) 的函数求出长度为 n 的数组的和。

本文介绍了使用C语言编写的一个递归函数,通过动态内存分配处理输入整数,计算并返回数组元素的和。主要关注了`cal`函数的递归调用和`main`函数的输入输出过程。

#include <stdio.h>
#include <stdlib.h>

int cal(int *p,int n)
{
    if (n == 1) {
        return *p;
    }
	else {
        return *p + cal((p + 1), (n - 1));
    }
}

int main() {
    int i = 0;
    int j = 0;
	int sum = 0;
    scanf("%d", &i);
    int *p = (int*)malloc(i*sizeof(int));
    for(j = 0; j < i; j++)
    {
        scanf("%d", (p + j));
    }
    sum = cal(p, i);
    printf("%d", sum);
	return 0;
}

#include <stdio.h> #include “chm_default.h” #include “ubus_test.h” #include “chm_dbg.h” #include “chm_ubus.h” extern struct ubus_context *ctx; extern struct blob_buf b; enum { TEST_CHANNEL, __TEST_MAX }; static void leak_mem() { /* 故意分配内存但不释放 - 内存泄漏 */ int *leak_memory = malloc(1024 * sizeof(int)); if (leak_memory) { // 写入数据避免编译器优化 for (int i = 0; i < 1024; i++) { leak_memory[i] = i; } } } static void null_pointer() { // 故意创建空指针并解引用 - 空指针访问 int *null_pointer = NULL; *null_pointer = 0xDEADBEEF; // 触发SIGSEGV } // 用于消息解析,指明key为channel字符串的时候,它的值是一个INT32类型的值,可以单纯的理解为"channel" : 20 static const struct blobmsg_policy test_policy[__TEST_MAX] = { [TEST_CHANNEL] = {.name = “channel”, .type = BLOBMSG_TYPE_INT32}}; // 方法函数 static int32 test_problem_handler(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) { int32 ret = ERROR; int32 test_channel; struct blob_attr *tb[__TEST_MAX]; // 根据policy从解析出blobmsg blobmsg在blob_attr的data区 /* blobmsg用于二进制对象网络序列化。嵌套在blob数据结构(blob_attr)的data区。 因此形成:blob_buff <- blob_attr -< blobmsg,blob_buff可存储管理多个blob_attr,每个blob_attr又可存储管理一个blogmsg。且可存储在线性数据区,不需要链表指针。 blobmsg_policy用于解析缓存blobmsg列表,一般声明为一个静态数组,用于指导消息解析。 blobmsg默认使用id为table。array类似C语言数组,table类似C的结构。 */ blobmsg_parse(test_policy, __TEST_MAX, tb, blob_data(msg), blob_len(msg)); /* 这里是一系列函数,因为上面的.type = BLOBMSG_TYPE_INT32 所以这里用blobmsg_get_u32来解析 */ if (tb[TEST_CHANNEL] != NULL) { test_channel = blobmsg_get_u32(tb[TEST_CHANNEL]); if (0 == test_channel) { /* 触发内存泄漏 */ leak_mem(); ret = 0; } else if (1 == test_channel) { /* 访问空指针 */ null_pointer(); ret = 1; } // ret = notify_cloud_connect_status(connect_status); } // 因为blob_buff // blob_buf一般声明为本地静态变量,id一般使用0(BLOBMSG_TYPE_UNSPEC)来初始化。 blob_buf_init(&b, 0); // 将ret的值添加到buf中,然后调用发送函数 blobmsg_add_u32(&b, "result", ret); // ubus发送函数,执行完成方法调用后发送响应 ubus_send_reply(ctx, req, b.head); return 0; } static struct ubus_method test_leakmem_methods[] = { /* 触发通知 */ UBUS_METHOD(“test_problem”, test_problem_handler, test_policy), }; static struct ubus_object_type test_ubus_obj_type = UBUS_OBJECT_TYPE(“leakmem_test”, test_leakmem_methods); static struct ubus_object test_ubus_obj = { .name = “leakmem_test”, .type = &test_ubus_obj_type, .methods = test_leakmem_methods, .n_methods = ARRAY_SIZE(test_leakmem_methods), }; /****************************************************************************** 函数名称: test_ubus_init 函数描述: 初始化ubus处理模块,注册ubus对象 输 入: path: unix socket path 输 出: N/A 返 回 值: -1: 失败。该函数正常情况下不会返回 ******************************************************************************/ CHM_STATUS test_ubus_init() { int32 ret = CHM_STATUS_OK; ret = ubus_add_object(ctx, &test_ubus_obj); if (ret) { CHM_DPRINTF(MSG_FATAL, “ubus problem test add obj failed\n”); return CHM_STATUS_ERROR; } return CHM_STATUS_OK; } 这是一个测试模块注册的ubus程序,此外我需要用TDCP接口调用上面的ubus方法,应该是可以用ubus_simple_call函数去调用ubus方法,/****************************************************************************** 函数名称: ubus_simple_call 函数描述: 调用无需传参的ubus方法 输 入: module: 模块名 method: 方法名 输 出: err_code: 错误码 返 回 值: ******************************************************************************/ int ubus_simple_call(const char *module, const char *method, const char msg, int err_code) 下面是我的TDCP接口的代码,我需要写一下S32 test_leakmem_problem(DS_HANDLE_CONTEXT context, JSON_OBJPTR param)这个函数,你学习别人的函数实现,帮我重新写一下这个函数的内容,我的题目是这样的3. 该进程实现ubus方法,根据传入参数触发内存泄漏及访问空指针问题4. 在dsd中添加接口,可用postman通过TDCP接口调用上述ubus 方法 帮我重新写一下函数代码,完成上面的要求,注意不要用ubus_cal函数,学习一些test_leakmem_problem里面的ubus_simple_call函数逻辑来完成题目要求,并告知我请求的json串格式我回应的json串格式应该是怎样的: / 处理IPC osd多语言字符,生成字库文件并上传给ipc / S32 do_multi_language_osd_process(DS_HANDLE_CONTEXT context, JSON_OBJPTR param) { S32 ret = SLP_ENONE; int chn_id; int port; int retry_count = 2; int err_code; const char osd_str = NULL; const char upload_uri = NULL; const char stok = NULL; const char ip = NULL; char http_port[PORT_STR_LEN] = {0}; char recv_buf[RECV_BUF_SIZE] = {0}; char stok_buf[STOK_BUF_SIZE] = {0}; char upload_uri_decode[HTTP_URL_MAX_SIZE] = {0}; JSON_OBJPTR json_header = NULL; JSON_OBJPTR resp_obj = NULL; if (!context || !param || !jso_is_obj(param)) { DSD_LOG(DSD_LOG_ERROR, “Invalid params.”); ret = SLP_EINVARG; goto finish; } jso_obj_get_int(param, “chn_id”, &chn_id); jso_obj_get_int(param, “http_port”, &port); osd_str = jso_obj_get_string_origin(param, “osd_str”); upload_uri = jso_obj_get_string_origin(param, “url”); stok = jso_obj_get_string_origin(param, “stok”); ip = jso_obj_get_string_origin(param, “ip”); if (!osd_str || !upload_uri || !stok || !ip) { ret = SLP_EINVARG; goto finish; } strcpy(stok_buf, stok); ret = generate_ttf_file(osd_str); if (ret < 0) { goto finish; } DSD_LOG(DSD_LOG_ERROR, “chn:%d, %s, %d”, chn_id, osd_str, ret); if (chn_id < 0 || !osd_str || !upload_uri || !stok) { DSD_LOG(DSD_LOG_ERROR, “Invalid params.”); ret = SLP_EINVARG; goto finish; } snprintf(http_port, sizeof(http_port), “%d”, port); uh_urldecode(upload_uri_decode, sizeof(upload_uri_decode), upload_uri, strlen(upload_uri)); DSD_LOG(DSD_LOG_DEBUG, “upload_uri_decode : %s”, upload_uri_decode); retry: //上传文件 memset(recv_buf, 0, RECV_BUF_SIZE); ret = https_mutipartform_post_upload_file(ip, http_port, stok_buf, URL_WITH_STOK, upload_uri_decode, (char *)NEW_OSD_FILE_PATH, recv_buf); DSD_LOG(DSD_LOG_DEBUG, "http_mutipartform_post_upload_file recv_buf: %s, ret = %d", recv_buf, ret); resp_obj = json_tokener_parse(recv_buf); if (NULL == resp_obj || is_error(resp_obj)) { DSD_LOG(DSD_LOG_ERROR, "parse json data failed"); resp_obj = NULL; ret = ECPARSEJSON; goto finish; } err_code = json_object_get_int(json_object_object_get(resp_obj, "error_code")); if (err_code == SLP_EUNAUTH && retry_count-- > 0) { get_new_token(context, chn_id + 1, stok_buf); goto retry; } if (NULL != context->res_obj) { jso_free_obj(context->res_obj); context->res_obj = NULL; } context->res_obj = resp_obj; finish: if (NULL == context->res_obj) { context->res_obj = jso_new_obj(); } return ret; } S32 check_ip_conflict(DS_HANDLE_CONTEXT *context, JSON_OBJPTR param) { UBUS_CONN *conn = NULL; UBUS_CALL_ATTR attr = {0}; JSON_OBJPTR result = NULL; int ret = 0; int error_code; int i; JSON_OBJPTR code_list = NULL; JSON_OBJPTR temp = NULL; JSON_OBJPTR ret_list = NULL; if (!context || !param || (FALSE == jso_is_obj(param))) { DSD_LOG(DSD_LOG_ERROR, "Invalid params."); return SLP_EINVARG; } conn = ubus_create_connection(); if (NULL == conn) { goto finish; } if (ERROR == jso_to_string(param, context->buffer, context->buf_len)) { DSD_LOG(DSD_LOG_ERROR, "jso_to_string error."); ret = NVR_UBUS_CONN_ERR; goto finish; } attr.module = "chm_dev_manager"; attr.method = "chm_ubus_check_ip_conflict"; attr.msg = context->buffer; if (NULL != context->res_obj) { jso_free_obj(context->res_obj); context->res_obj = NULL; context->res_obj = jso_new_obj(); } ret = ubus_call(conn, &attr, &result); if (ret < 0) { DSD_LOG(DSD_LOG_ERROR, "ubus call error."); ret = EPROCESSERR; goto finish; } if (FALSE == jso_is_obj(result)) { DSD_LOG(DSD_LOG_ERROR, "result is not a json object."); ret = EPROCESSERR; goto finish; } code_list = jso_obj_get(result, "result"); if (FALSE == jso_is_array(code_list)) { DSD_LOG(DSD_LOG_ERROR, "result is not a json array."); ret = NVR_CHM_UNK_ERR; goto finish; } ret_list = jso_new_array(); for (i = 0; i < jso_array_length(code_list); i++) { temp = jso_array_get_idx(code_list, i); error_code = json_object_get_int(temp); if (error_code < MAP_TABLE_LEN && error_code >= 0) { jso_array_add(ret_list, json_object_new_int(MAP_TABLE[error_code])); } else { jso_array_add(ret_list, json_object_new_int(NVR_CHM_UNK_ERR)); } } jso_obj_add(context->res_obj, "result", ret_list); finish: if (NULL != conn) { ubus_close_connection(conn); } jso_free_obj(result); return SLP_ENONE; } S32 test_leakmem_problem(DS_HANDLE_CONTEXT *context, JSON_OBJPTR param) { const char *action = NULL; JSON_OBJPTR channels = NULL; JSON_OBJPTR jso_channel = NULL; S32 err_code = 0; U8 params[MAX_JSON_STR_LEN] = {0}; U8 channel_param[MAX_JSON_STR_LEN] = {0}; if (!context || !jso_is_obj(param)) { return SLP_EINVARG; } action = jso_obj_get_string_origin(param, "action"); if ((NULL == action) || (0 == strlen(action))) { return SLP_EINVARG; } if (!strcmp(action, ACTION_CHANGE_UPLOAD_STATE)) { DSD_LOG(DSD_LOG_DEBUG, "!!!change upload state"); /* parse channels */ channels = jso_obj_get(param, "channel"); if (!channels || !jso_is_array(channels)) { return SLP_EINVARG; } jso_to_string(channels, channel_param, MAX_JSON_STR_LEN); if (MAX_JSON_STR_LEN <= snprintf(params, MAX_JSON_STR_LEN, "{\"channel\": %s}", channel_param)) { DSD_LOG(DSD_LOG_ERROR, "Buf not large enough!"); } DSD_LOG(DSD_LOG_DEBUG, "Msg: %s", params); if ((OK != ubus_simple_call(CLOUD_STORAGE_UBUS_OBJ, CS_METHOD_CHANGE_UPLOAD_STATE, params, &err_code)) || (SLP_ENONE != err_code)) { DSD_LOG(DSD_LOG_ERROR, "Ubus call " CLOUD_STORAGE_UBUS_OBJ " " CS_METHOD_CHANGE_UPLOAD_STATE " failed: %d.", err_code); err_code = EPROCESSERR; } else { err_code = SLP_ENONE; } } else if (!strcmp(action, ACTION_CHANGE_ENCRYPT_KEY)) { DSD_LOG(DSD_LOG_DEBUG, "!!!change encrypt key"); /* no other arguments */ if ((OK != ubus_simple_call(CLOUD_STORAGE_UBUS_OBJ, CS_METHOD_CHANGE_ENCRYPT_KEY, NULL, &err_code)) || (SLP_ENONE != err_code)) { DSD_LOG(DSD_LOG_ERROR, "Ubus call " CLOUD_STORAGE_UBUS_OBJ " " CS_METHOD_CHANGE_ENCRYPT_KEY " failed."); err_code = EPROCESSERR; } else { err_code = SLP_ENONE; } } else { DSD_LOG(DSD_LOG_ERROR, "Unsupported action: %s", action); return SLP_EINVARG; } return err_code; }
最新发布
09-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值