2

I can't figure out what I'm doing wrong. I am learning C so sorry if this is obviously wrong, but I'm trying to use uthash to make a hash map of stocks and their prices. But when I add stocks to my hash map, I get the above error.

What I did was take the example from their site and ran it to make sure it worked, once it worked as expected I changed the values to fit my problem. In the original code, the variable id in the struct was an integer but I changed it to a char(instead of number, I wanted to use the stock ticker as the key), then I started to the following errors:

../src/stackCsamples.c:87: warning: passing argument 1 of '__builtin_object_size' makes pointer from integer without a cast
../src/stackCsamples.c:87: warning: passing argument 1 of '__builtin_object_size' makes pointer from integer without a cast
../src/stackCsamples.c:87: warning: passing argument 1 of '__builtin___strcpy_chk' makes pointer from integer without a cast
../src/stackCsamples.c:87: warning: passing argument 1 of '__inline_strcpy_chk' makes pointer from integer without a cast
../src/stackCsamples.c:89: warning: passing argument 1 of 'strlen' makes pointer from integer without a cast
../src/stackCsamples.c:89: warning: passing argument 1 of 'strlen' makes pointer from integer without a cast
../src/stackCsamples.c:89: warning: passing argument 1 of 'strlen' makes pointer from integer without a cast

The problem seems to be with two lines here(87) which is strcpy(s->id, user_id); and (89) which is: HASH_ADD_STR( users, id, s );

How am I using both of these wrong? I looked strcpy up and it looks like it takes 3 items, but when I add the size I still get errors.

Here's a snippet of the parts I think are relevant:

#include <stdio.h>   /* gets */
#include <stdlib.h>  /* atoi, malloc */
#include <string.h>  /* strcpy */
#include "uthash.h"

struct my_struct {
    char id;                    /* key */
    float price;
    UT_hash_handle hh;         /* makes this structure hashable */
};

struct my_struct *users = NULL;

void new_stock(char *user_id, float price) {
    struct my_struct *s;

    s = (struct my_struct*)malloc(sizeof(struct my_struct));
    strcpy(s->id, user_id);
    s->price = price;
    HASH_ADD_STR( users, id, s );  /* id: name of key field */
}

int main() {
    printf("starting..");
    new_stock("IBM", 10.2);
    new_stock("goog", 2.2);
    return 0;
}
4

2 回答 2

3

With this line:

strcpy(s->id, user_id);

You are trying to copy a string onto a char. Note that both arguments to strcpy are to be pointers to chars: char *.

Furthermore, note that you'll also need to make some space in memory for s->id, as a char[] or a char *. Hint: you've made space for the struct, but that only includes enough space for a single character for id.

If you want to use C then you should get a copy of K&R, but failing that, you might spend some time reviewing this.

于 2012-06-05T03:04:04.347 回答
1

You need to provide enough space in the structure for the user ID array, or dynamically allocate enough space. For instance, you might do:

enum { MAX_ID_LEN = 32 };
struct my_struct
{
    char id[MAX_ID_LEN];                    /* key */
    float price;
    UT_hash_handle hh;         /* makes this structure hashable */
};

Then you could use:

strcpy(s->id, user_id);

as long as you've checked that user_id is not longer than 31 characters plus null before hand. If you've not done that check, you should. If you refuse to do that check and don't mind truncating overlong user ID strings, then you could use:

strncpy(s->id, user_id, sizeof(s->id) - 1);
s->id[sizeof(s->id)-1] = '\0';

This ensures null termination; just using strncpy() alone does not. Beware, if the string (s->id) was much longer, you could find your code wasting time zeroing out the tail end of the string.


The residual warnings about strlen() are hidden by the HASH_ADD_STR() macro, but likely come from the same problem as the strcpy() warnings did — the s->id field was not a character pointer or a character array. The amended structure will likely quash those warnings too. For us to be sure, you'd have to show the definition of HASH_ADD_STR() and any macros it invokes.

于 2012-06-05T03:12:19.767 回答