0

I'm dynamically repeatedly creating a char[] of fixed length 32 and pass it to function that stores the pointer in a struct and passes it later on to a callback function.

Unforntunately I don't know the correct way to allocate the memory for this string data.

This is the function, where the nonceHex is created in a loop

static int polling_thread(struct pt *pt, uint16_t ticks)
{
    static uint16_t timer;
    timer += ticks;

    PT_BEGIN(pt);

    while (1)
    {
        uint8_t nonce[NONCE_LEN] = {};
        char nonceHex[2 * NONCE_LEN] = "";
        RNG(nonce, NONCE_LEN);
        hex_encode(nonce, sizeof(nonce), nonceHex);
        
        ...

        struct mg_connection *c = mg_connect_http(mgos_get_mgr(), http_cb, nonceHex, url, (const char *)sEtagHeader, NULL);

        ...

        timer = 0;
        PT_WAIT_UNTIL(pt, timer >= 500);
    }

    PT_END(pt);
}

And this is the callback function where the char[] is passed by the framework (mongoose os) as cb_arg

static void http_cb(struct mg_connection *nc, int ev, void *evd, void *cb_arg)
{
    ...

    case MG_EV_HTTP_REPLY:
    {
        const char *nonceHex = (const char *)cb_arg;
        LOG(LL_DEBUG, ("http_cb nonce: %s", nonceHex));
        LOG(LL_DEBUG, ("http_cb nc->user_data: %s", (const char *)nc->user_data));
    }
    
    ...
}

Unfortunately when I run this code I don't received the nonceHex but something that looks like unitialized char[]

http_cb nonce: Pa�?`B�?�a�?���?�c�?
http_cb nc->user_data: Pa�?`B�?�a�?���?�c�?

Do I need to dynamically malloc the char[]? If I use a static char[] it works, but it's not correct as nonceHex is overwritten by subsequent loop cycles and so cb_arg in the callback function contains invalid data.

Can anyone tell me how this would be programmed correctly?

#######################################################

Changed my function to

static int polling_thread(struct pt *pt, uint16_t ticks)
{
    static uint16_t timer;
    timer += ticks;

    PT_BEGIN(pt);

    while (1)
    {
        ...

        uint8_t nonce[NONCE_LEN] = {};
        char *nonceHex = malloc(2 * NONCE_LEN + 1);
        RNG(nonce, NONCE_LEN);
        hex_encode(nonce, sizeof(nonce), nonceHex);
        *(nonceHex+2 * NONCE_LEN) = '\0';
        
        struct mg_connection *c = mg_connect_http(mgos_get_mgr(), http_cb, nonceHex, url, (const char *)sEtagHeader, NULL);
        
        ...

        timer = 0;
        PT_WAIT_UNTIL(pt, timer >= 500);
    }

    PT_END(pt);
}

Added call to free in callback function

static void http_cb(struct mg_connection *nc, int ev, void *evd, void *cb_arg)
{
    ...

    case MG_EV_HTTP_REPLY:
    {
        char *nonceHex = (char *)cb_arg;
        LOG(LL_DEBUG, ("http_cb nonce: %s", nonceHex));
        LOG(LL_DEBUG, ("http_cb nc->user_data: %s", (const char *)nc->user_data));
        free(nonceHex);
    }
    
    ...
}

This results in a panic

Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.

Can you see my fault?

  • use `strdup(nonceHex)` to make a dynamic copy of your string – tstanisl Jun 09 '22 at 08:37
  • changed function call to `struct mg_connection *c = mg_connect_http(mgos_get_mgr(), http_cb, strdup(nonceHex), url, (const char *)sEtagHeader, NULL);` Unfortunately now the program panics. – Marko Seidenglanz Jun 09 '22 at 08:46
  • @user3386109 malloc gives me **CORRUPT HEAP: multi_heap.c:439 detected at 0x3ffbc134 ** error. Is this the correct way ```char *nonceHex = (char *)malloc(2 * NONCE_LEN);``` and free in callback function after processing ```free(nonceHex);``` – Marko Seidenglanz Jun 09 '22 at 08:55
  • ```char nonceHex[2 * NONCE_LEN+1]; RNG(nonce, NONCE_LEN); hex_encode(nonce, sizeof(nonce), nonceHex); nonceHex[2 * NONCE_LEN] = 0; char *nonceHexCopy = strdup(nonceHex); struct mg_connection *c = mg_connect_http(mgos_get_mgr(), http_cb, nonceHexCopy, url, (const char *)sEtagHeader, NULL);``` this is the code change I made (free is called in callback handler) ... ```Error: Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.``` What am I doing wrong? – Marko Seidenglanz Jun 09 '22 at 09:14
  • 1
    Add new paragraphs to your question containing the things you have tried. – Ian Abbott Jun 09 '22 at 09:24
  • It is really hard to tell for sure but it is quite probable that the error is not in the part you have shown. Please try to post a [mcve] (a self-contained short program that anyone can copy, paste, compile and run in a couple of clicks). – n. m. could be an AI Jun 09 '22 at 10:43
  • @n.1.8e9-where's-my-sharem. This is hard to do, because it runs on an ESP32 and uses mongoose os framework. So from looking at my code you would say that malloc is used correctly? – Marko Seidenglanz Jun 09 '22 at 11:06
  • 1
    Yes sometimes it is hard to come with a reproduction. You can try and mock the parts of the framework you think are necessary but of course it may be hard and no success is guaranteed. I don't see a problem with your use of malloc. You should make sure `free` is not called twice on the same pointer though. If you can receive two MG_EV_HTTP_REPLY on the same connection then this might be a problem. – n. m. could be an AI Jun 09 '22 at 13:14
  • Thanks for your advice. The hint with the repeated call to free was correct. I now call it on CONNECTION CLOSE event and it works better, though it still freezes at some point in time... Nevertheless the malloc seems to be the right thing here. Thank you very much. – Marko Seidenglanz Jun 09 '22 at 13:53

0 Answers0