设置调整大小时出现内存错误
Memory error in set resize
这是我写的集合结构:
struct state_set
{
struct state ***state_array;
size_t *slot_sizes;
size_t *slot_memory;
};
这是一个初始化程序:
struct state_set *state_set_init()
{
struct state_set *new_set =
malloc(sizeof(struct state_set));
new_set->state_array = malloc(ARRAY_SIZE * sizeof(struct state**));
new_set->slot_sizes = malloc(ARRAY_SIZE * sizeof(size_t));
new_set->slot_memory = malloc(ARRAY_SIZE * sizeof(size_t));
for (int i = 0; i < ARRAY_SIZE; i++)
{
new_set->slot_sizes[i] = 0;
new_set->slot_memory[i] = INITIAL_SLOT_SIZE;
}
for (int i = 0; i < ARRAY_SIZE; i++)
{
new_set->state_array[i] =
malloc(new_set->slot_memory[i] * sizeof(struct state*));
error_validate_pointer(new_set->state_array[i]);
}
return new_set;
}
还有一个导致内存错误的调整大小函数:
void state_set_resize_slot(struct state_set *set, int slot_i)
{
struct state **to_resize = set->state_array[slot_i];
to_resize =
realloc(to_resize, set->slot_memory[slot_i] * 2 * sizeof(struct state*));
error_validate_pointer(to_resize);
set->slot_memory[slot_i] *= 2;
}
问题是 - 为什么 state_set_resize_slot()
不起作用?我看不出这个 realloc 有什么错误,而且我已经盯着这段代码至少看了一个小时了。 (很明显,realloc 是我所有麻烦的根源)。或者调整大小函数写得很好,我应该在其他地方寻找错误?
编辑:
如果有人想查看完整代码,可在此处获取:
http://pastebin.com/bfH3arDi(散列函数 returns 1 而不是 h 因为我正在测试碰撞,而且初始化函数和析构函数也已过时,现在我正在为 slot_memory 和 slot_sizes 而不是使用堆栈)。
下面是 运行 程序的 valgrind 输出,该程序添加了多个要设置的状态(错误大约在第三次调整大小时):
==20979== Invalid write of size 8
==20979== at 0x400C21: state_set_add (state_set.c:93)
==20979== by 0x400781: main (main.c:22)
==20979== Address 0x51f2320 is 0 bytes inside a block of size 40 free'd
==20979== at 0x4C2BB1C: realloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==20979== by 0x4009CD: state_set_resize_slot (state_set.c:54)
==20979== by 0x400B23: state_set_add (state_set.c:78)
==20979== by 0x400781: main (main.c:22)
==20979==
==20979== Invalid free() / delete / delete[] / realloc()
==20979== at 0x4C2BB1C: realloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==20979== by 0x4009CD: state_set_resize_slot (state_set.c:54)
==20979== by 0x400B23: state_set_add (state_set.c:78)
==20979== by 0x4007B2: main (main.c:23)
==20979== Address 0x51f2320 is 0 bytes inside a block of size 40 free'd
==20979== at 0x4C2BB1C: realloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==20979== by 0x4009CD: state_set_resize_slot (state_set.c:54)
==20979== by 0x400B23: state_set_add (state_set.c:78)
==20979== by 0x400781: main (main.c:22)
==20979==
a.out: state_set.c:20: error_validate_pointer: Assertion `ptr != ((void *)0)' failed.
在您的函数中,您将指针放入 to_resize
,然后您 realloc
内存,但您从未将新指针设置回 set->state_array[slot_i]
,因此它丢失了并且您继续使用旧的、已经释放的内存 space 并将指向其范围之外。
这是我写的集合结构:
struct state_set
{
struct state ***state_array;
size_t *slot_sizes;
size_t *slot_memory;
};
这是一个初始化程序:
struct state_set *state_set_init()
{
struct state_set *new_set =
malloc(sizeof(struct state_set));
new_set->state_array = malloc(ARRAY_SIZE * sizeof(struct state**));
new_set->slot_sizes = malloc(ARRAY_SIZE * sizeof(size_t));
new_set->slot_memory = malloc(ARRAY_SIZE * sizeof(size_t));
for (int i = 0; i < ARRAY_SIZE; i++)
{
new_set->slot_sizes[i] = 0;
new_set->slot_memory[i] = INITIAL_SLOT_SIZE;
}
for (int i = 0; i < ARRAY_SIZE; i++)
{
new_set->state_array[i] =
malloc(new_set->slot_memory[i] * sizeof(struct state*));
error_validate_pointer(new_set->state_array[i]);
}
return new_set;
}
还有一个导致内存错误的调整大小函数:
void state_set_resize_slot(struct state_set *set, int slot_i)
{
struct state **to_resize = set->state_array[slot_i];
to_resize =
realloc(to_resize, set->slot_memory[slot_i] * 2 * sizeof(struct state*));
error_validate_pointer(to_resize);
set->slot_memory[slot_i] *= 2;
}
问题是 - 为什么 state_set_resize_slot()
不起作用?我看不出这个 realloc 有什么错误,而且我已经盯着这段代码至少看了一个小时了。 (很明显,realloc 是我所有麻烦的根源)。或者调整大小函数写得很好,我应该在其他地方寻找错误?
编辑:
如果有人想查看完整代码,可在此处获取: http://pastebin.com/bfH3arDi(散列函数 returns 1 而不是 h 因为我正在测试碰撞,而且初始化函数和析构函数也已过时,现在我正在为 slot_memory 和 slot_sizes 而不是使用堆栈)。
下面是 运行 程序的 valgrind 输出,该程序添加了多个要设置的状态(错误大约在第三次调整大小时):
==20979== Invalid write of size 8
==20979== at 0x400C21: state_set_add (state_set.c:93)
==20979== by 0x400781: main (main.c:22)
==20979== Address 0x51f2320 is 0 bytes inside a block of size 40 free'd
==20979== at 0x4C2BB1C: realloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==20979== by 0x4009CD: state_set_resize_slot (state_set.c:54)
==20979== by 0x400B23: state_set_add (state_set.c:78)
==20979== by 0x400781: main (main.c:22)
==20979==
==20979== Invalid free() / delete / delete[] / realloc()
==20979== at 0x4C2BB1C: realloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==20979== by 0x4009CD: state_set_resize_slot (state_set.c:54)
==20979== by 0x400B23: state_set_add (state_set.c:78)
==20979== by 0x4007B2: main (main.c:23)
==20979== Address 0x51f2320 is 0 bytes inside a block of size 40 free'd
==20979== at 0x4C2BB1C: realloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==20979== by 0x4009CD: state_set_resize_slot (state_set.c:54)
==20979== by 0x400B23: state_set_add (state_set.c:78)
==20979== by 0x400781: main (main.c:22)
==20979==
a.out: state_set.c:20: error_validate_pointer: Assertion `ptr != ((void *)0)' failed.
在您的函数中,您将指针放入 to_resize
,然后您 realloc
内存,但您从未将新指针设置回 set->state_array[slot_i]
,因此它丢失了并且您继续使用旧的、已经释放的内存 space 并将指向其范围之外。