strcat的分段错误

ben*_*sky 2 c string segmentation-fault strcat

我在strcat和分段错误方面遇到了一些问题.错误如下:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000000
0x00007fff82049f1f in __strcat_chk ()
(gdb) where
#0  0x00007fff82049f1f in __strcat_chk ()
#1  0x0000000100000adf in bloom_operation (bloom=0x100100080, item=0x100000e11 "hello world", operation=1) at bloom_filter.c:81
#2  0x0000000100000c0e in bloom_insert (bloom=0x100100080, to_insert=0x100000e11 "hello world") at bloom_filter.c:99
#3  0x0000000100000ce5 in main () at test.c:6
Run Code Online (Sandbox Code Playgroud)

bloom_operation如下:

int bloom_operation(bloom_filter_t *bloom, const char *item, int operation)
{
    int i;    

    for(i = 0; i < bloom->number_of_hash_salts; i++)
    {
        char temp[sizeof(item) + sizeof(bloom->hash_salts[i]) + 2];
        strcat(temp, item);
        strcat(temp, *bloom->hash_salts[i]);

        switch(operation)
        {
            case BLOOM_INSERT:
                bloom->data[hash(temp) % bloom->buckets] = 1;
                break;
            case BLOOM_EXISTS:
                if(!bloom->data[hash(temp) % bloom->buckets]) return 0;
                break;
        }    
    }

    return 1;
}
Run Code Online (Sandbox Code Playgroud)

有麻烦的线是第二个 strcat.bloom-> hash_salts是结构的一部分,定义如下:

typedef unsigned const char *hash_function_salt[33];
typedef struct {
    size_t buckets;    
    size_t number_of_hash_salts;
    int bytes_per_bucket;
    unsigned char *data;
    hash_function_salt *hash_salts;
} bloom_filter_t;
Run Code Online (Sandbox Code Playgroud)

它们在这里初始化:

bloom_filter_t* bloom_filter_create(size_t buckets, size_t number_of_hash_salts, ...) 
{
    bloom_filter_t *bloom;
    va_list args;
    int i;

    bloom = malloc(sizeof(bloom_filter_t));
    if(bloom == NULL) return NULL;

    // left out stuff here for brevity...

    bloom->hash_salts = calloc(bloom->number_of_hash_salts, sizeof(hash_function_salt));

    va_start(args, number_of_hash_salts);

    for(i = 0; i < number_of_hash_salts; ++i)
        bloom->hash_salts[i] = va_arg(args, hash_function_salt);

    va_end(args);

    // and here...
}
Run Code Online (Sandbox Code Playgroud)

并且bloom_filter_create的调用方式如下:

bloom_filter_create(100, 4, "3301cd0e145c34280951594b05a7f899", "0e7b1b108b3290906660cbcd0a3b3880", "8ad8664f1bb5d88711fd53471839d041", "7af95d27363c1b3bc8c4ccc5fcd20f32");
Run Code Online (Sandbox Code Playgroud)

我做错了什么,但我真的迷失了什么.提前致谢,

本.

Mar*_*ins 9

我看到了几个问题:

char temp[sizeof(item) + sizeof(bloom->hash_salts[i]) + 2];
Run Code Online (Sandbox Code Playgroud)

sizeof(item)仅将(在64位的平台上或8)返回4.您可能需要使用strlen()作为实际长度.虽然我不认为你可以像使用strlen那样在堆栈上声明它(虽然我想也许我看到有人表示有可能使用更新版本的gcc - 我可能会出去吃午餐).

另一个问题是临时数组未初始化.所以第一个strcat可能不会写入数组的开头.在调用strcat之前,它需要在第一个元素中放置一个NULL(0).

它可能已经被删除了,但我没有看到你number_of_hash_salts在结构中初始化了成员.

  • 我会使用strcpy而不是第一个strcat.这样你就不必浪费时间来初始化temp. (4认同)
  • 是的,您可以使用`strlen`和最近的gcc(recent = 3.x,iirc)在堆栈上声明它.这是一个C99功能.不过,我不知道MSVC是否会选择它. (2认同)