我对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:6bloom_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;
}有麻烦的是第二条线。bloom>散列盐类是结构的一部分,定义如下:
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;它们在这里初始化:
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...
}bloom_filter_create的名称如下:
bloom_filter_create(100, 4, "3301cd0e145c34280951594b05a7f899", "0e7b1b108b3290906660cbcd0a3b3880", "8ad8664f1bb5d88711fd53471839d041", "7af95d27363c1b3bc8c4ccc5fcd20f32");我做错了什么,但我真的不知道是什么。提前谢谢你,
本。
发布于 2010-07-15 22:58:09
你需要使用斯特伦,而不是大号。item作为指针传入,而不是作为数组传入。
这句话:
char temp[sizeof(item) + sizeof(bloom->hash_salts[i]) + 2];将使温度达到指针+ 2长度的34倍。项目的大小是指针的大小,sizeof(bloom->hash_salts[i])当前是指针大小的33倍。
您需要对item使用strlen,这样您就可以知道实际的字符数。
其次,bloom->hash_salts[i]是一个hash_function_salt,它是一个由33个指向char的指针组成的数组。似乎应该将hash_function_salt定义为:
因为你希望它能容纳33个字符,而不是33个指针。您还应该记住,当您将字符串文本传递给bloom_filter_create时,您传递的是一个指针。这意味着初始化使用memcpy或strcpy的hash_function_salt数组。当我们知道确切的长度时,memcpy会更快(比如这里):
所以我们得到:
typedef unsigned char hash_function_salt[33];在bloom_filter_create中
memcpy(bloom->hash_salts[i], va_arg(args, char*), sizeof(bloom->hash_salts[i]));回到bloom_operation,我们得到:
char temp[strlen(item) + sizeof(bloom->hash_salts[i])];
strcpy(temp, item);
strcat(temp, bloom->hash_salts[i]);我们使用strlen来表示条目,因为它是一个指针,而sizeof用于hash_function_salt,它是一个固定大小的char数组。我们不需要添加任何内容,因为hash_function_salt已经为NUL提供了空间。我们首先使用strcpy。strcat用于当您已经拥有一个以NUL结尾的字符串(我们这里没有)。请注意,我们删除了*。这是一个错误,因为你的错误类型胡作非为。
发布于 2010-07-15 22:59:14
我看到了一些问题:
char temp[sizeof(item) + sizeof(bloom->hash_salts[i]) + 2];sizeof(item)只返回4(或者在64位平台上返回8)。您可能需要使用strlen()来表示实际长度。虽然我不认为你可以像斯特伦那样在堆栈上声明它(虽然我想我可能看到有人暗示gcc的新版本是可能的--我可能会出去吃午饭)。
另一个问题是未初始化temp数组。因此,第一个strcat可能不会写入数组的开头。它需要在调用strcat之前在第一个元素中放入一个NULL (0)。
它可能已经在被剪掉的代码中了,但是我没有看到您在结构中初始化了number_of_hash_salts成员。
发布于 2010-07-15 23:00:11
temp的数组大小计算使用sizeof(bloom->hash_salts[i]) (即指针的大小),但随后取消引用指针,并尝试将整个字符串复制到temp中。
https://stackoverflow.com/questions/3260684
复制相似问题