我想实现一个用于获取自定义类型参数的变量函数,而不是像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;
}
它适用于two 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;
}
发布于 2018-05-28 09:16:43
我看到的问题是,您的add_node()
似乎会检查NULL
参数以确定参数列表是否已完成,但您在调用它时从不传递NULL
参数,因此add_node
将在遍历您传递的所有参数后继续读取不存在的“参数”,访问内存中它不应该访问的位置,并导致各种糟糕的问题。
https://stackoverflow.com/questions/50337390
复制相似问题