我试图在C中实现一个动态列表,我不明白为什么我会得到“堆栈周围的变量'内存'被损坏。”错误时,我试图添加第二个项目的列表。
struct LIST {
unsigned int size;
unsigned int count;
void** items;
};
struct LIST* list_init(unsigned int size)
{
struct LIST* createList = (struct LIST*)calloc(1, sizeof(struct LIST));
void* memory = calloc(size, sizeof(void*));
if (memory == 0 || createList == 0) return 0;
createList->items = &memory;
createList->size = size;
return createList;
}
void list_add(struct LIST* list, void* item)
{
if (list->count + 1 > list->size)
{
void* memory = realloc(list->items, (sizeof(void*)) * list->count + 1);
list->items = &memory;
return;
}
else
{
list->items[list->count] = item;
list->count = list->count + 1;
}
}
int main()
{
const char* str = "Hello";
struct LIST* list = list_init(2);
list_add(list, (void*)str);
list_add(list, (void*)str);
list_add(list, (void*)str);
list_add(list, (void*)str);
printf("Items in List: %d \n\n", list_count(list));
list_clear(list);
free(list);
return 0;
}
代码永远不会进入可以对内存变量做任何事情的if块,但是在第二个list_add Call中,它在退出函数时崩溃(注意,我使用VS2022调试器来单步调试它)。
我希望有2个项目添加到列表之前realloc是用来扩展列表的一个。
1条答案
按热度按时间raogr8fs1#
有几个问题...
1.在
LIST
中,items
应该是void *
,而不是void **
1.在
list_add
中,memory
是超出作用域的堆栈局部变量。1.您只需在
realloc
中使用list->count + 1
。我们希望将list->size
递增并在调用中使用它。1.实际的存储代码(在
else
块中)应该无条件地执行1.存储代码尝试取消引用
void *
指针1.由于列表存储的是 * 字符串 *(即
char *
数组),因此在存储时需要复制字符串。因此,我们应该使用strdup
1.由于新的
strdup
,仅仅在最后执行free(list)
是不够的。我们需要循环所有元素并释放在list_add
中复制的字符串。list_init
正在复制list_add
中的代码。它应该只执行 * 第一个 *calloc
。1.因为我们 * 可以 * 传入字符串 * 文字 * 到
list_add
(例如list_add(list,"Hello");
,第二个参数应该有const
。下面是重构后的代码。它带有bug和修复的注解:
在上面的代码中,我使用了
cpp
条件来表示旧代码和新代码:注意:这可以通过
unifdef -k
运行文件来清理。下面是程序输出:
下面是清理后的代码: