由C++中try的内存管理引发的逆天bug

文章讲述了在C++编程中遇到的问题,涉及socket服务端的创建、析构函数的使用以及内存管理。作者在try-catch块中初始化Server对象,导致对象在try块外被销毁,进而影响到套接字的监听操作。尝试用new手动管理内存,但遇到了未初始化指针的编译错误。
摘要由CSDN通过智能技术生成

太逆天了,一定要记录一下

起因是这样:
我在写一个socket的服务端,我写了一个server类,socket是类的一个成员变量,在类初始化时创建,并在析构函数中关闭(划重点,等会要考)。简化后的定义如下:

class Server {
public:
	Server() {};
	Server(string root) {
		// 创建套接字 并 绑定端口
		this->serverSocket = socket(AF_INET, SOCK_STREAM, 0);
		//中间省略一堆配置
		bind(this->serverSocket, (sockaddr*)&serverAddress, sizeof(serverAddress);
	}
	~Server() {
		closesocket(this->serverSocket);
	}
	
	void working() {
		if (listen(this->serverSocket, 3) < 0) {
			cout << "Listen error";
		}
	}
private:
	SOCKET serverSocket;
};

为什么要定义一个空初始化?Server() {};
请看下面的代码:

int main() {
	Server server;
	try {
		server = Server(root);	//root是一个字符串路径,指示远程库的根目录
		break;
	}
	catch (const exception& error) {
		cout << error.what() << endl;
		cout << "Please retype." << endl;
	}
	server.working();
	return 0;
}

可以看到我用了try,因为我希望在server初始化时进行错误检查,包括路径合不合法、套接字创建成不成功等等。但问题也就出在这里

根据C++的内存管理,try代码块内部定义的变量是个局部变量,出了try就会被销毁,所以如果我不在try外部先声明server,那么后面的代码就拿不到server变量。但我只在外部声明,并不进行初始化,所以就定义了一个空初始化

嗯,这样子写,代码是合法了,不报错了。但问题依然存在:try代码块内部定义的server实例在出了try之后还是会被销毁!

就是因为这个问题,我在调试代码的时候一直报错“Listen error”。原因就是server实例在出了try之后调用了析构函数,而我在析构函数里写了closesocket(this->serverSocket);,把套接字给关了。

那我想算了,手动new一个对象,手动管理内存吧。结果还是报错!

int main() {
	Server* server;
	for (int i = 0; i < 3; ++i) {
		try {
			//cin >> root;
			server = new Server(root);
			break;
		}
		catch (const exception& error) {
			cout << error.what() << endl;
			cout << "Please retype." << endl;
		}
	}
	server->working();
	delete server;
	return 0;
}

报错:

error C4703: 使用了可能未初始化的本地指针变量“server”

离谱呀离大谱

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白草遥遥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值