printf()似乎正在破坏我的数据

loc*_*red 3 c gdb nginx

我正在用C编写一个nginx模块,并且有一些非常奇怪的结果.我从我的模块中提取了一个函数来测试它的输出以及相关的nginx类型/宏定义.

我正在我的build_key_hash_pair函数中构建一个结构,然后printf()对其中的内容进行处理main.当我printf在内部函数里面的数据时,main输出是有效的.当我删除printf内部函数内部时,main打印一个空字符串.这很令人困惑,因为在调用build_key_hash_pairI 之后,除了显示它之外,我没有对数据进行操作.这是代码:

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

typedef struct ngx_str_t {
    size_t          len;
    char            *data;
} ngx_str_t;

typedef uintptr_t   ngx_uint_t;

typedef struct key_hash_pair {
    ngx_uint_t      hash;
    ngx_str_t       key;
} key_hash_pair;

#define ngx_string(str)     { sizeof(str) - 1, (char *) str }
#define ngx_str_set(str, text)                                               \
    (str)->len = sizeof(text) - 1; (str)->data = (char *) text
#define ngx_hash(key, c)    ((ngx_uint_t) key * 31 + c)
#define ngx_str_null(str)   (str)->len = 0; (str)->data = NULL

void build_key_hash_pair(key_hash_pair *h, ngx_str_t api_key, ngx_str_t ip);

int main (int argc, char const *argv[])
{
    ngx_str_t api_key = ngx_string("86f7e437faa5a7fce15d1ddcb9eaeaea377667b8");
    ngx_str_t ip = ngx_string("123.123.123.123");

    key_hash_pair *pair;
    pair = malloc(sizeof(key_hash_pair));
    build_key_hash_pair(pair, api_key, ip);

    printf("api_key = %s\n", api_key.data);
    printf("ip = %s\n", ip.data);

    printf("pair->key = %s\n", pair->key.data);
    printf("pair->hash = %u\n", (unsigned int)pair->hash);

    return 0;
}

void build_key_hash_pair(key_hash_pair *h, ngx_str_t api_key, ngx_str_t ip)
{
    ngx_str_null(&h->key);

    char str[56];
    memset(str, 0, sizeof(str));
    strcat(str, api_key.data);
    strcat(str, ip.data);
    ngx_str_set(&h->key, str);

    ngx_uint_t i;
    for (i = 0; i < 56; i++) {
        h->hash = ngx_hash(&h->hash, h->key.data[i]);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我printf("hello")build_key_hash_pair函数内部执行时的输出:

helloapi_key = 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8
ip = 123.123.123.123
pair->key = 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8123.123.123.123
pair->hash = 32509824
Run Code Online (Sandbox Code Playgroud)

当我不在printf里面时,这是(奇异)输出build_key_hash_pair:

api_key = 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8
ip = 123.123.123.123
pair->key = 
pair->hash = 32509824
Run Code Online (Sandbox Code Playgroud)

如您所见,pair->key没有数据.在gdb中,如果我在main之后调用断点build_key_hash_pair,则pair->key包含相应的数据.但在第一次打电话之后printf,它就被淘汰了.内存地址保持不变,但数据刚刚消失.谁能告诉我世界上我做错了什么?

int*_*jay 7

这行是个问题:

ngx_str_set(&h->key, str);
Run Code Online (Sandbox Code Playgroud)

str是一个局部变量,你在里面放了一个指针h->key,它将被返回给调用者.后build_key_hash_pair返回时,指针将不再有效.当你没有调用任何其他函数时,指针仍然指向相同的值,但这不是你可以依赖的东西.调用printf覆盖堆栈的那部分.

您需要的是用malloc或动态分配字符串,或者strdupkey_hash_pair结构中放置一个数组来保存密钥(如果密钥总是相同的大小,则可能).