简体   繁体   English

我不明白的释放后堆使用

[英]Heap use after free that i don't understand

I know from previous C projects that ASAN tells me "heap-use-after-free" when I try to access to a pointer after the use offree() but in this case I don't even understand because i use free() at the end of the main and do nothing after.我从以前的 C 项目中知道,当我在使用 offree() 后尝试访问指针时,ASAN 告诉我“heap-use-after-free”,但在这种情况下,我什至不明白,因为我在主要结束后什么也不做。

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

#define URL "URL"
#define API_KEY "KEY"

void add_parameter(char *query, char *key, char *value)
{
    const size_t new_len = strlen(query) + strlen(key) + strlen(value) + 3; 
    query = realloc(query, new_len * sizeof(char));
    if (query)
    {
        strcat(query, "?");
        strcat(query, key);
        strcat(query, "=");
        strcat(query, value);
        query[new_len - 1] = '\0';
        printf("%s\n", query);
    }
}

int main()
{
    char *query = malloc((strlen(URL) + 1) * sizeof(char));
    memcpy(query, URL, sizeof(URL));

    add_parameter(query, "api_key", API_KEY);
    printf("%s\n", query);
    free(query);

    return 0;
}

Thanks for your help谢谢你的帮助

The following line can cause a problem以下行可能会导致问题

query = realloc(query, new_len * sizeof(char));

As the value of query could change.因为query的值可能会改变。 It, main .它, main it is unaware of this change.它不知道这种变化。 Pass the updated version of query back to main .query的更新版本传递回main

For starters the pointer query is passed to the function add_parameter by value对于初学者,指针query按值传递给 function add_parameter

add_parameter(query, "api_key", API_KEY);

It means that the function deals with a copy of the value of the pointer query within the function.这意味着 function 处理 function 内的指针query值的副本。

Changing the copy does not reflect on the original pointer query .更改副本不会反映原始指针query The original pointer query passed to the function by value stays unchanged.按值传递给 function 的原始指针query保持不变。

You need to pass the pointer by reference.您需要通过引用传递指针。

Passing by reference in C means passing an object indirectly through a pointer to it.在 C 中通过引用传递意味着通过指向它的指针间接传递 object。 Dereferencing the pointer you will have a direct access to the original object.取消引用指针,您将可以直接访问原始 object。

In this case the function will be declared like在这种情况下,function 将被声明为

int add_parameter(char **query, const char *key, const char *value);

(as the strings pointed to by the parameters key and value are not changed within the function the parameters should be declared with the qualifier const ) and within the function you have to write (由于参数keyvalue指向的字符串在 function 中未更改,因此应使用限定符const声明参数)并且在 function 中您必须编写

int add_parameter( char **query, const char *key, const char *value )
{
    const size_t new_len = strlen( query ) + strlen( key ) + strlen( value ) + 3; 
    char *tmp = realloc( query, new_len * sizeof( char ) ); 

    int success = tmp != NULL;

    if ( success )
    {
        strcat( rmp, "?" );
        strcat( tmp, key );
        strcat( tmp, "=" );
        strcat( tmp, value );
        printf("%s\n", tmp);
   
        *query = tmp;
    }

    return success;
}

This statement within the function function内的此声明

tmp[new_len - 1] = '\0';

is redundant.是多余的。 So it is removed所以它被删除

Pay attention to that realloc can return a null-pointer.注意realloc可以返回一个空指针。 In this case if not to use the intermediate variable tmp the early allocated memory can be lost.在这种情况下,如果不使用中间变量tmp ,早期分配的 memory 可能会丢失。

The function can be called like function 可以这样称呼

add_parameter( &query, "api_key", API_KEY);

or或者

if ( add_parameter( &query, "api_key", API_KEY) )
{
    //...
}
else
{
    //...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM