今天研究用回溯法解决八皇后问题,碰到了一个有趣的小问题。

看这篇随笔前,最好先看看我上一篇所写的 c++ 内存分配中一个有趣的小问题

先看代码

 #pragma once
#pragma execution_character_set("utf-8")
#include <iostream>
#include <cstdio>
using std::cout;
using std::endl; const int COLUMNS = ;
const int ROWS = ;
int Matrix[COLUMNS][ROWS] = { }; void print()
{
for (int row = ; row < ROWS; ++row)
{
for (int col = ; col < COLUMNS; ++col)
{
cout << Matrix[row][col] << " ";
}
cout << endl;
}
cout << endl;
} bool check(int row, int col)
{
//检查列
for (int r = ; r < row; ++r)
{
if (Matrix[r][col])
return false;
}
for (int r = row - , c = col - ; r != - && c != -; --r, --c)
{
if (Matrix[r][c])
return false;
}
for (int r = row - , c = col + ; r != - && c != COLUMNS; --r, ++c)
{
if (Matrix[r][c])
return false;
}
return true;
} void writeQueen(int currentRow)
{
static int count = ;
if (currentRow == ROWS)
{
++count;
cout << count << endl;
print();
//return; //此处应有return,问题代码正是由于这儿没有写return导致后面访问越界而产生的。
} int col = ;
for (; col < COLUMNS; ++col)
{
Matrix[currentRow][col] = ;
//print();
if (check(currentRow, col))
writeQueen(currentRow + );
Matrix[currentRow][col] = ;
}
} int main()
{
writeQueen();
}

运行出来后结果是这样的:

即每个结果的序号都是1,明显不符合我的意图。

之后就是寻找错误原因了,定位到这一段代码上:

 void writeQueen(int currentRow)
{
static int count = ;
if (currentRow == ROWS)
{
++count;
cout << count << endl;
print();
//return; //此处应有return,问题代码正是由于这儿没有写return导致后面访问越界而产生的。
} int col = ;
for (; col < COLUMNS; ++col)
{
Matrix[currentRow][col] = ;
//print();
if (check(currentRow, col))
writeQueen(currentRow + );
Matrix[currentRow][col] = ;
}
}

打断点进行调试。

发现当执行Matrix[currentRow][col] = 0;这一句代码后count的值由1变为了0。

为什么会这样呢?我看了一下地址:

他两的地址居然是同一个!

为什么会出现这种情况?

count和Matrix都定义在全局区,Matrix的初始化语句为Matrix[8][8],原本Matrix所控制的内存空间与count的并不冲突,可是我访问Matrix时却越界了,我访问的是Matrix[8][0],而系统在分配内存时却恰好将count分配到了Matrix之后,这两变量的缘分太深了,没办法。。。由此造成了内存污染,当修改Matrix时无意中也造成了count被修改。

所以,归根结底还是访问越界了!

c++ 中全局/静态存储区的内存污染问题的更多相关文章

  1. C++内存分配方式详解——堆、栈、自由存储区、全局/静态存储区和常量存储区

    栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区.里面的变量通常是局部变量.函数参数等.在一个进程中,位于用户虚拟地址空间顶部的是用户栈,编译器用它来实现函数的调用.和堆一样 ...

  2. C++内存分区:堆、栈、自由存储区、全局/静态存储区和常量存储区

    日志                                                                                                  ...

  3. 【校招面试 之 C/C++】第14题 C++ 内存分配方式详解——堆、栈、自由存储区、全局/静态存储区和常量存储区(堆栈的区别)

    栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区.里面的变量通常是局部变量.函数参数等.在一个进程中,位于用户虚拟地址空间顶部的是用户栈,编译器用它来实现函数的调用.和堆一样 ...

  4. (转)C++内存分配方式详解——堆、栈、自由存储区、全局/静态存储区和常量存储区

    程序在内存有五个存在区域: A:动态区域中的栈区  B:动态区域中的栈区 C:静态区域中:全局变量 和静态变量    (这个区域又可以进一步细分为:初始化的全局变量和静态变量    以及    未初始 ...

  5. 【转】C中的静态存储区和动态存储区

    一.内存基本构成    可编程内存在基本上分为这样的几大部分:静态存储区.堆区和栈区.他们的功能不同,对他们使用方式也就不同.    静态存储区:内存在程序编译的时候就已经分配好,这块内存在程序的整个 ...

  6. c++ 堆、栈、自由存储区、全局/静态存储区和常量存储区

    在C++中,内存分成5个区,他们分别是堆.栈.自由存储区.全局/静态存储区和常量存储区. 栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区.里面的变量通常是局部变量.函数参数 ...

  7. linux面试之--堆、栈、自由存储区、全局/静态存储区和常量存储区

    栈,就是那些由编译器在须要的时候分配,在不须要的时候自己主动清除的变量的存储区.里面的变量一般是局部变量.函数參数等.在一个进程中.位于用户虚拟地址空间顶部的是用户栈,编译器用它来实现函数的调用.和堆 ...

  8. [整理]C中的静态存储区

    静态存储区:即内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.它主要存放静态数据.全局数据和常量.栈区:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些 ...

  9. Java中的堆内存、栈内存、静态存储区

    一.栈 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用.但缺点是,存在栈中的数据大小与生存 ...

随机推荐

  1. Class 'org.apache.tomcat.jdbc.pool.DataSource' not found

    把项目移动到新的运行环境时,明明包都导入了,项目也放进tomcat里面了,但是还会找不到该类 解决方法:项目右键选择底下的Properties ->project facets ->jav ...

  2. [转]C#中的abstract 类和方法

    转:https://www.cnblogs.com/zzy2740/archive/2005/09/20/240808.html C#中的abstract类不能被实例化,他只提供其他类的继承的接口 u ...

  3. 小白学 Python 爬虫(38):爬虫框架 Scrapy 入门基础(六) Item Pipeline

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  4. Shell脚本传递带有空格的参数

    在另一博文<Shell脚本实现DB2数据库表导出到文件>中实现了通过脚本实现将DB2数据库导出到文件,需要传入七个参数,最后一个是一个带有空格字符串,所以传入的时候有点问题,会自动识别空格 ...

  5. 三、Spring Cloud之软负载均衡 Ribbon

    前言 上一节我们已经学习了Eureka 注册中心,其实我们也使用到了Ribbon ,只是当时我们没有细讲,所以我们现在一起来学习一下Ribbon. 什么是Ribbon 之前接触到的负载均衡都是硬负载均 ...

  6. vuex使用面板报 Unexpected token错误

    Module build failed: SyntaxError: D:/frontend/webtest/src/components/mutations.vue: Unexpected token ...

  7. 【LC_Lesson1】--字符串反转练习

    LeetCode算法练习题目一: 给定一个字符串,要求将该字符串反转后输出 努力学习,天天向上.借助LeetCode的题目,练习编码能力,数据结构,以及C++和Python的编码能力. 一. 算法实现 ...

  8. 关于将vs项目推到GitHub上遇到的问题

    想整理下项目,然后通过vs推到github下. 1.在vs上创建好了一个程序.点中解决方案-->右键-->将项目加入代码库. 2.在github上创建好一个仓库,然后复制下https 3. ...

  9. VMware Workstation CentOS7 Linux 学习之路(1)--系统安装

      前言 很早就想学习Linux了,出去面试很多家公司都问会不会Linux,都很尴尬,一直没学过Linux,在网上也看过很多资料,也安装了VM,自己摸索着学习Linux,之前看网上的一些命令一顿操作, ...

  10. CAS是什么

    CAS是什么? 比较并交换 例子1: public class ABADemo1 { public static void main(String[] args) { AtomicInteger at ...