我想实现一个variadic函数,它获取自定义类型参数,而不像GNU的例子:
https://www.gnu.org/software/libc/manual/html_node/Variadic-Example.html#Variadic-Example
在我的逻辑中,我处理节点,由此tpye定义:
typedef struct node_t {
char *key;
node_type_t type;
apr_array_header_t *arr_strings;
apr_array_header_t *arr_numbers;
} node_t;
这样的节点根据以这种方式定义的特定类型(字符串,数字)类型在不同的APR数组中存储信息:
typedef enum node_type_t {
node_type_string,
node_type_number,
} node_type_t;
该功能如下所示:
int add_node(apr_pool_t *p_pool, node_t *p_target_node, ...) {
int rv = 0;
va_list lmnts;
va_start(lmnts, p_target_node);
node_t *n = va_arg(lmnts, node_t *);
apr_array_header_t *tbl;
do {
switch(n->type) {
case node_type_string:
tbl = p_target_node->arr_strings;
break;
case node_type_number:
tbl = p_target_node->arr_numbers;
break;
default:
break;
}
printf("\t\t%d - %s\n", rv, n->key);
*(const node_t**)apr_array_push(tbl) = n;
rv++;
} while (n && ((n = va_arg(lmnts, node_t *)) != NULL) && apr_strnatcmp(n->key, p_target_node->key) != 0);
va_end(lmnts);
return rv;
}
它适用于两个 node_t 参数但是对于更多我得到分段错误。
这是完整的代码:
#include <stdarg.h>
#include <stdio.h>
#include <apr_general.h>
#include <apr_hash.h>
#include <apr_pools.h>
#include <apr_strings.h>
#include <apr_tables.h>
typedef enum node_type_t {
node_type_string,
node_type_number,
} node_type_t;
typedef struct node_t {
char *key;
node_type_t type;
apr_array_header_t *arr_strings;
apr_array_header_t *arr_numbers;
} node_t;
node_t *create_node(apr_pool_t *p_pool, char *p_key, node_type_t p_type) {
node_t *NODE = apr_palloc(p_pool, sizeof(node_t));
NODE->key = p_key;
NODE->type = p_type;
NODE->arr_strings = apr_array_make(p_pool, 0, sizeof(node_t*));
NODE->arr_numbers = apr_array_make(p_pool, 0, sizeof(node_t*));
return NODE;
}
int add_node(apr_pool_t *p_pool, node_t *p_target_node, ...) {
int rv = 0;
va_list lmnts;
va_start(lmnts, p_target_node);
node_t *n = va_arg(lmnts, node_t *);
apr_array_header_t *tbl;
do {
switch(n->type) {
case node_type_string:
tbl = p_target_node->arr_strings;
break;
case node_type_number:
tbl = p_target_node->arr_numbers;
break;
default:
break;
}
printf("\t\t%d - %s\n", rv, n->key);
*(const node_t**)apr_array_push(tbl) = n;
rv++;
} while (n && ((n = va_arg(lmnts, node_t *)) != NULL) && apr_strnatcmp(n->key, p_target_node->key) != 0);
va_end(lmnts);
return rv;
}
int add_node(apr_pool_t *p_pool, node_t *p_target_node, ...) {
int rv = 0;
va_list lmnts;
va_start(lmnts, p_target_node);
node_t *n = va_arg(lmnts, node_t *);
while((n = va_arg(lmnts, node_t *)) != NULL && apr_strnatcmp(n->key, p_target_node->key) != 0) {
printf("\t\t%d - %s\n", rv, n->key);
*(const node_t**)apr_array_push(p_target_node->arr_strings) = n;
rv++;
}
va_end(lmnts);
return rv;
}
int main(int argc, const char *argv[]) {
apr_status_t rv;
apr_pool_t *mp;
rv = apr_initialize();
if (rv != APR_SUCCESS) {
return -1;
}
apr_pool_create(&mp, NULL);
node_t *ROOT_NODE = create_node(mp, "THE_ROOT", node_type_string);
printf("\tROOT_NODE { key: '%s', type: %d, [%d, %d]}\n",
ROOT_NODE->key, ROOT_NODE->type,
ROOT_NODE->arr_strings->nelts, ROOT_NODE->arr_numbers->nelts);
node_t *NODE_A = create_node(mp, "A", node_type_string);
printf("\tNODE_A { key: '%s', type: %d, [%d, %d]}\n",
NODE_A->key, NODE_A->type,
NODE_A->arr_strings->nelts, NODE_A->arr_numbers->nelts);
node_t *NODE_B = create_node(mp, "B", node_type_number);
printf("\tNODE_B { key: '%s', type: %d, [%d, %d]}\n",
NODE_B->key, NODE_B->type,
NODE_B->arr_strings->nelts, NODE_B->arr_numbers->nelts);
node_t *NODE_C = create_node(mp, "C", node_type_string);
printf("\tNODE_C { key: '%s', type: %d, [%d, %d]}\n",
NODE_C->key, NODE_C->type,
NODE_C->arr_strings->nelts, NODE_C->arr_numbers->nelts);
add_node(mp, ROOT_NODE, NODE_A, NODE_B, NODE_C);
printf("\tn = %d, n = %d\n", ROOT_NODE->arr_strings->nelts, ROOT_NODE->arr_numbers->nelts);
apr_pool_destroy(mp);
apr_terminate();
return 0;
}
答案 0 :(得分:1)
我看到的问题是你的add_node()
似乎检查了一个NULL
参数来确定参数列表已经完成,但是当你调用时你永远不会传递NULL
参数它,所以add_node
将继续阅读不存在的“参数”,在它通过您传递的所有参数后,访问内存中不应该存在的位置,并导致各种不良问题。