C++ N皇后问题中vector的push_back与[]赋值结果差异原因求解
N皇后代码初始化问题解析
两种写法的行为差异
- 原代码
board[i] = s的执行逻辑:
初始化时写了vector<string> board(n),这一步会直接生成包含n个默认构造的空字符串的vector,此时vector的size为n。循环中board[i] = s是对已经存在的第i个元素赋值,将空字符串替换为长度为n、全为.的字符串。循环结束后vector的size依然是n,每个元素的长度都是n,完全符合后续回溯逻辑的访问要求。 - 替换为
board.push_back(s)后的异常逻辑:
初始化vector<string> board(n)已经生成了n个空字符串,push_back操作是在现有元素的末尾追加新元素,循环n次后vector的size会变成n + n = 2n,前n个元素始终是空字符串,只有后n个是我们需要的全.字符串。后续回溯逻辑中row的取值范围是0~n-1,操作的都是前n个空字符串,对空字符串执行board[row][col]属于数组越界访问。
底层原理
C++中std::vector的带整数参数的构造函数,会直接完成n个元素的初始化而非仅预留空间,此时访问[0, n-1]区间的元素是合法的,但元素本身是空string,长度为0。std::string的operator[]不会做下标越界检查,越界访问属于未定义行为,运行时可能读取到随机内存值、触发段错误,这就是你看到奇怪随机符号、提交报错的根本原因。
如果想要使用push_back方式初始化,只需要把初始化语句改为vector<string> board;,不预先创建n个空元素,push_back n次后vector的size就是n,即可正常运行。
内容的提问来源于stack exchange,提问作者MenoMore
相关产品推荐
相关产品推荐

