VS编译器BUG分享 【未加载 wntdll.pdb】

今早写链表的代码时,出现了未加载 wntdll.pdb这样一个问题。此贴将总结出现这类问题的原因和解决方法。(不断更新)

先上图:

出现这个异常,基本和堆区的重复内存释放没跑。

情况一:深拷贝与浅拷贝

如果一个类的成员变量,是开放在堆区的,

那么我们必须要重载拷贝构造函数。

因为默认的拷贝构造函数是浅拷贝,只是单纯的赋值。

举个例子来讲解:

class Person
{
public:
	int* age;

	Person(int age)
	{
		this->age = new int(age);
	}

	//Person(Person& p)
	//{
	//	this->age = new int(*(p.age));
	//}

	~Person()
	{
		if (this->age != NULL)
			free(this->age);
		this->age = NULL;
	}
};

int main()
{
	Person p1(5);
	Person p2(p1);
	return 0;
}

我们创建了一个人类,其姓名是一个整型指针。

这里如果不进行深拷贝,那么会这样:

第一个人p1,他的成员变量age指向堆区的某个地址x。 

这时候我们创建了一个人p2,用浅拷贝拷贝了p1。

那么他也有一个成员变量age,指向同一个地址x。

进行析构函数时,

p1和p2会进行对这个地址的两次释放,也就是内存重复释放,

所以出现了这个错误。

改进方法是,重载拷贝函数,在堆区重新开辟一块同样大小的新空间,然后让本对象的本成员函数指向那块新空间即可。

Person(Person& p)
{
	this->age = new int(*(p.age));
}

情况二:反转链表 操纵的是同一个链表

因为指针指向的是地址,操控的是地址,

所以如果几个指针指向同一块地址的话,

其中一个指针改变其指向,会影响全局。(和单纯的数据不一样)

比如看如下代码:

LinkedList Reverse(LinkedList& L)
{
	Node* pre;
	Node* cur;
	Node* nex;
	Node* head;

	head = (Node*)malloc(sizeof(Node));
	pre = NULL;
	cur = L->next;
	nex = NULL;
	while (cur != NULL)
	{
		nex = cur->next;
		cur->next = pre;
		pre = cur;
		cur = nex;
	}
	head->next = pre;
	free(cur);
	cur = NULL;
	free(nex);
	nex = NULL;

	return head;
}
	cout << "请输入单链表的数据:";
	LinkedList list, start;
	list = LinkedListCreatT();
	//LinkedListDelete(list, 3);
	for (start = list->next; start != NULL; start = start->next)
	{
		cout << start->data << " ";
	}
	cout << endl;
	LinkedList list2 = Reverse(list);
	for (start = list->next; start != NULL; start = start->next)
	{
		cout << start->data << " ";
	}
	cout << endl;
	LinkedListFree(list);
	LinkedListFree(list2);
	if (list == NULL)
	{
		cout << "链表已释放完毕" << endl;
	}

这里的Reverse(list)其实就是list,而list2也是list,

结果我们重复使用了两次free函数来释放list,

自然会造成堆区内存重复释放。

猜你喜欢

转载自blog.csdn.net/Kukeoo/article/details/114170651