Giter Site home page Giter Site logo

shput never fills in "key" field about stb HOT 7 CLOSED

jgarvin avatar jgarvin commented on June 30, 2024
shput never fills in "key" field

from stb.

Comments (7)

nothings avatar nothings commented on June 30, 2024 1

shgetp is only meant to be used with shputs

from stb.

nothings avatar nothings commented on June 30, 2024 1

Yes, shput is a string table, so it needs to be a char*, not a char[].

Using sh_new_strdup or sh_new_arena is not required, but you'll have to manually manage the string storage yourself.

Also, you can't provide a fixed char[] array in the structure and then point to it with a char *key, because the hash table will move around in memory and invalidate the pointer.

from stb.

nothings avatar nothings commented on June 30, 2024

I mean, it's possible there's still a bug even on that path, I didn't test.

from stb.

jgarvin avatar jgarvin commented on June 30, 2024

This has been a point of confusion for me. I'd expect most people want to give a key and get back a pointer to the stored value to avoid copying. But hmget/shget return TV not TV*, that's why I went with shgetp, but shgetp seemed a bit less convenient because it returns T* instead of TV*. But I guess if you only ever use it with shputs then T* and TV* are the same?

from stb.

jgarvin avatar jgarvin commented on June 30, 2024

I've updated it to use shputs but now it won't compile

#define STB_DS_IMPLEMENTATION
#include "stb_ds.h"

struct table_entry {
    char key[33];
    int x;
};

int main()
{
    struct table_entry* table = NULL;
    struct table_entry* w = shgetp_null(table, "test");
    if(!w)
    {
        struct table_entry new_entry;
        memset(&new_entry, 0, sizeof(new_entry));
        strcpy(new_entry.key, "test");
        shputs(table, new_entry);
        w = shgetp_null(table, "test");
        if(!strcmp(w->key, "test") == 0)
        {
            abort();
        }
    }
    return 0;
}
$ gcc -O0 -g3 test.c 
In file included from test.c:2:
stb_bug.c: In function ‘main’:
stb_ds.h:616:33: error: assignment to expression with array type
  616 |      (t)[stbds_temp((t)-1)].key = stbds_temp_key((t)-1)) // above line overwrites whole structure, so must rewrite key here if it was allocated internally
      |                                 ^
stb_ds.h:436:21: note: in expansion of macro ‘stbds_shputs’
  436 | #define shputs      stbds_shputs
      |                     ^~~~~~~~~~~~
stb_bug.c:18:9: note: in expansion of macro ‘shputs’
   18 |         shputs(table, new_entry);
      |         ^~~~~~

Does key need to be char* ? Does shputs require using sh_new_strdup or sh_new_arena?

from stb.

nothings avatar nothings commented on June 30, 2024

You could just use char key[33] with hm_ functions if you always use char key[33] for everything and always 0 out the entire key after the end of the string, but then you can't use string literals.

from stb.

jgarvin avatar jgarvin commented on June 30, 2024

Thanks, got it working. I wasn't sure how the memory management for the key on the item you pass to shputs would work when using strdup/arena but valgrind seems to indicate that that's up to you to handle freeing. This compiles and runs with no leaks or other errors, in case somebody stumbles on this later:

#define STB_DS_IMPLEMENTATION
#include "stb_ds.h"

struct table_entry {
    char* key;
    int x;
};

int main()
{
    struct table_entry* table = NULL;
    sh_new_strdup(table);
    struct table_entry* w = shgetp_null(table, "test");
    if(!w)
    {
        struct table_entry new_entry;
        memset(&new_entry, 0, sizeof(new_entry));
        new_entry.key = malloc(strlen("test")+1);
        strcpy(new_entry.key, "test");
        shputs(table, new_entry);
        free(new_entry.key);
        w = shgetp_null(table, "test");
        if(!strcmp(w->key, "test") == 0)
        {
            abort();
        }
    }
    shfree(table);
    return 0;
}

from stb.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.