私はC言語でnginxモジュールを書いていますが、奇妙な結果があります。関連するnginxの型/マクロ定義だけでなく、その出力をテストするために私のモジュールから関数を抽出しました。printf()が私のデータを破壊しているようです
私のbuild_key_hash_pair
関数で構造体を構築していて、という内容のprintf()
を実行しています。 printf
内部関数内のデータがmain
の出力に有効です。内側の関数の中のprintf
を削除すると、main
は空文字列を出力します。これは、build_key_hash_pair
への関数呼び出しの後で、データを表示する以外は操作していないため、混乱します。ここでは、コードです:私はbuild_key_hash_pair
関数内printf("hello")
を行うときにここで
#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]);
}
}
が出力されます:私はbuild_key_hash_pair
内部printf
をしていないとき
helloapi_key = 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8
ip = 123.123.123.123
pair->key = 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8123.123.123.123
pair->hash = 32509824
そして、ここでは(奇妙な)出力されます。
api_key = 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8
ip = 123.123.123.123
pair->key =
pair->hash = 32509824
ご覧のとおり、pair->key
にはデータがありません。 gdbでは、メインの呼び出しの直後にブレークポイントをbuild_key_hash_pair
にすると、pair->key
に適切なデータが含まれています。しかし、printf
への最初の呼び出しの後、それは消去されます。メモリアドレスは同じですが、データは消えてしまいました。誰でも私が間違っている世界の何を教えてもらえますか?
多分私は何かが欠落していますが、これらの文字列のヌルターミネータはどこにありますか? – KevinDTimm
文字列定数は、最後に明示的なヌルバイトを必要としません。これらはコンパイラによって追加されます。 –