0

次の機能を考慮します。

int get_timestamp(json_object *json_obj, double *timestamp) {
    json_object *value_obj;
    int status;
    if (json_object_object_get_ex(json_obj, "timestamp", &value_obj)) {
        if (json_object_is_type(value_obj, json_type_double)) {
            *timestamp = json_object_get_double(value_obj);
            status = JSONPARSER_OK;
        }
        else
            status = JSONPARSER_EBADTYPE;
    } else
        status = JSONPARSER_ENODENOTFOUND;
    free(value_obj);
    return status;
}

int get_display_name(json_object *json_obj, char **display_name) {
    json_object *value_obj;
    int status;
    const char* holder;
    if (json_object_object_get_ex(json_obj, "display_name", &value_obj)) {
        if (json_object_is_type(value_obj, json_type_string)) {
            // The returned string memory is managed by the json_object and will
            // be freed when the reference count of the json_object drops to zero.
            holder = json_object_get_string(value_obj);
            strcpy(*display_name, holder);
            status = JSONPARSER_OK;
        }
        else
            status = JSONPARSER_EBADTYPE;
    } else
        status = JSONPARSER_ENODENOTFOUND;
    free(value_obj);
    return status;
}

int get_organization(json_object *json_obj, char **organization) {
    json_object *value_obj;
    int status;
    const char* holder;
    if (json_object_object_get_ex(json_obj, "organization", &value_obj)) {
        if (json_object_is_type(value_obj, json_type_string)) {
            // The returned string memory is managed by the json_object and will
            // be freed when the reference count of the json_object drops to zero.
            holder = json_object_get_string(value_obj);
            strcpy(*organization, holder);
            status = JSONPARSER_OK;
        }
        else
            status = JSONPARSER_EBADTYPE;
    } else
        status = JSONPARSER_ENODENOTFOUND;
    free(value_obj);
    return status;
}

使用されます:

json_object *response_obj, *idp_obj;
int status;
char *display_name;
char *organization;
response_obj = json_tokener_parse(raw_data);
json_object_object_get_ex(response_obj, "idp", &idp_obj);

get_timestamp(response_obj, timestamp);
get_display_name(idp_obj, &display_name);
get_organization(idp_obj, &organization);

free(idp_obj);
free(response_obj);
return status;

何が起こるのですか:

get_organization(idp_obj, &organization);1)すべてを削除すると、正常に動作するようです。

2)すべてを削除get_display_name(idp_obj, &display_name);すると、再び正常に動作するように見えます。

3)「そのまま」のコードではstrcpy、メソッド内で使用されるエラーがありますget_organization

No source available for "__strcpy_sse2_unaligned() at 0x7ffff763f001" 

この驚くほど難しい言語の知識を向上させるために、この振る舞いを理解したいと思っています。

4

1 に答える 1

0

そのエラー メッセージは、ソースを特定できない関数内にあるため、デバッガのエラー メッセージです。必要な作業は、コードに到達するまで関数呼び出しスタックをたどることだけです。

デバッガーがその関数で停止する理由については、実際には別の質問になるはずですが、とにかく答えます。渡す宛先ポインターが初期化されていないローカル変数であるため、未定義の動作display_nameが原因です。呼び出すコードではget_display_name、ローカル変数を宣言しますdisplay_nameが、初期化はしません。初期化されていない非静的ローカル変数の値はindeterminateであり、初期化せずに使用すると、未定義の動作が発生します。

この問題には基本的に 2 つの解決策があります。display_name固定サイズの配列として宣言するか、たとえば を使用して、有効な割り当てられたメモリを指すようにしますmalloc

変数でも同じ問題が発生しorganizationます。

于 2015-08-26T14:17:00.487 に答える