可以实现手机上对Shapefile文件的可视化与编辑.shape文件(shp格式)是由ESRI公司开发的一种矢量存储格式。一个shape文件包括一个主文件,一个索引文件,和一个dBASE表。其中主文件的后缀就是.shp。Shapefile文件用于描述几何体对象:点,折线与多边形,属于一种矢量图形格式,它能够保存几何图形的位置及相关属性。但这种格式没法存储地理数据的拓扑信息。Shapefile文件实际上该种文件格式是由多个文件组成的。

文件:url80.ctfile.com/f/25127180-740375684-b1d46a?p=551685 (访问密码: 551685)


我们都知道对指针( Pointer)的操作,实际上是对计算机内存地址的操作,通过访问内存地址实现间接访问该地址中保存的数据。其实就是CPU的寻址方式中的间接寻址。简单概括正常使用指针时的3个步骤为:

定义指针变量
绑定指针即给指针变量赋值
解引用即间接访问目标变量
通过一个简单的例子来看这3个步骤的实现:
复制代码
1 int a = 5;
2 //定义指针变量p
3 int *p;
4 //绑定指针,就是给指针变量赋值,指向另一个变量a(指针的用途就是指向别的变量)
5 p = &a;
6 //将6放入p所指向的那个变量的空间中,这里就是a的空间
7 *p = 6;
复制代码
可以看出,在定义指针变量p时,未初始化p,这个时候的p为随机值,此时解引用p是没有意义的,内存随机值的空间是否有效我们也不得而知。

    绑定指针就是将变量a的地址赋值给指针变量p,此时p就有了意义,明确了内存中访问的具体空间位置,p是指向变量a的空间的,变量a是有具体内容的,因此指针必须给它赋值才能解引用它。给指针变量p赋值实际上是在变量a前加一个“&”符号,这个符号是取地址符,&a就是指变量a的地址,编译器在给每个变量分配出内存空间,并将a与这块的内存空间地址绑定。这个地址只有编译器知道,而程序员并不知道编译器随机给这段空间分配什么随机地址值。程序员要获取或操作这个地址时,就需要使用取地址符。由上述分析看来,给p赋予了变量a地址的值是一个合法的,在内存中明确的地址值,这个值是受控的,同时通过访问指针间接访问该地址中保存的数据也是受控的,p就是一个正常的指针。相反,如果指针指向了内存中不可用的区域,或者是指针的值是非法的随机值也就是非正常内存地址,那么这个指针就是不受控的,同时通过访问指针间接访问该地址中保存的数据也是不受控的,同时是不可知的,此时这个指针就是野指针(Wild Pointer)。

二、需要明确的一点
野指针不同于空指针,所谓空指针,是给指针变量赋NULL值,即:

1 int *p = NULL;
所谓NULL值在C/C++中定义为:

1 #ifdef __cplusplus // 定义这个符号表示当前是C++环境中
2 #define NULL 0 // 在C++中NULL为0
3 #else
4 #define NULL (void *) 0 // 在C中的NULL是强制类型转换为void *的0
5 #endif
可以看出,给p赋值NULL值也就是让p指向空地址。在不同的系统中,NULL并不意味等于0,也有系统会使用地址0,而将NULL定义为其他值,所以不要把NULL和0等同起来。你可以将NULL通俗理解为是空值,也就是指向一个不被使用的地址,在大多数系统中,都将0作为不被使用的地址,因此就有了这样的定义,C或者C++编译器保证这个空值不会是任何对象的地址。

    void *表示的是“无类型指针”,可以指向任何数据类型,在这里void指针与空指针NULL区别:NULL说明指针不指向任何数据,是“空的”;而void指针实实在在地指向一块内存,只是不知道这块内存中是什么类型的数据。空指针的值是受控的,但并不是有意义的,我们是将指针指向了0地址,这个0地址就是作为内存中的一个特殊地址,因此空指针是一个对任何指针类型都合法的指针,但并不是合理的指针,指针变量具有空指针值,表示它处于闲置状态,没有指向任何有意义的内容。我们需要在让空指针真正指向了一块有意义的内存后,我们才能对它取内容。即:

1 int a = 5;
2 int *p = NULL;
3 p = &a;
NULL指针并没有危害,可以使用if语句来判断是否为NULL。

三、一些典型的error
我们要知道单纯的从语言层面无法判断一个指针所保存的地址是否是合法的,等到程序运行起来,配合硬件的内存实际地址,才能发现指针指向的地址是否是你想要让它指向的合理空间地址。在日常编码过程中有一些导致野指针或者内存溢出的错误编码方式:

1、指针变量未初始化
任何指针在被创建的时候,不会自动变成NULL指针,因此指针的值是一个随机值。这时候去解引用就是去访问这个地址不确定的变量,所以结果是不可知的。

1 void main()
2 {
3 char* p;
4 *p = 6; //错误
5 }
2、使用了悬垂指针
在C或者C++中使用malloc或者new申请内存使用后,指针已经free或者delete了,没有置为NULL,此时的指针是一个悬垂指针。

    free和delete只是把指针所指的内存给释放掉,并不会改变相关的指针的值。这个指针实际仍然指向内存中相同位置即其地址仍然不变,甚至该位置仍然可以被读写,只不过这时候该内存区域完全不可控即该地址对应的内存是垃圾,悬垂指针会让人误以为是个合法的指针。

复制代码
1 void main()
2 {
3 char* p = (char *) malloc(10);
4 strcpy(p, “abc”);
5 free§; //p所指的内存被释放,但是p所指的地址仍然不变
6 strcpy(p, “def”); // 错误
7 }
复制代码
3、返回栈内存指针或引用
在函数内部定义的局部指针变量或者局部引用变量不能作为函数的返回值,因为该局部变量的作用域范围在函数内部,该函数在被调用时,由于局部指针变量或者引用已经被销毁,因此调用时该内存区域的内容已经发生了变化,再操作该内存区域就没有具体的意义。

复制代码
1 char* fun1()
2 {
3 char* p = “hello”;
4 return p;
5 }
6
7 char* fun2()
8 {
9 char a = 6;
10 return &a;
11 }
12
13 void main()
14 {
15 char* p1 = fun1(); //错误
16 char* p2 = fun2(); //错误
17 }
复制代码
4、指针重复释放
复制代码
1 void fun(char* p, char len)
2 {
3 for(char i = 0; i < len; i++)
4 {
5 p[i] = i;
6 }
7 free§;
8 }
9
10 void main()
11 {
12 char * p1 = (char *)malloc(6 * sizeof(char));
13 fun(p1, 6);
14 free(p1); //重复释放指针导致错误
15 }
复制代码
5、数组越界
使用的数组长度超过了定义的数组长度。

1 void main()
2 {
3 int a[6];
4 for(int i = 0; i<=6; i++) //错误
5 }
6、内存分配后未初始化
复制代码
1 void main()
2 {
3 char* p = (char*)malloc(6);
4 printf§; //p未初始化
5 free§;
6 }
复制代码
7、使用的内存大小超过了分配的内存大小
复制代码
1 void main()
2 {
3 char* p = (char*)malloc(6);
4 for(int i = 0; i <= 6; i++) //错误
5 {
6 p[i] = i;
7 }
8 free§;
9 }
复制代码
四、避免错误的注意点
1、在定义指针变量时,要将其值置为NULL,即 char *p = NULL。

    2、在指针使用之前,需要给指针赋具体值,就是将其绑定一个可用地址空间让其有意义,即p = &a。3、在使用指针前,需要判断指针为非NULL,只有非NULL的指针才有意义。即判断if(p != NULL)。4、free或者delete指针后,需要将指针值置为NULL。5、malloc和free,new和delete注意配对使用,当 malloc或new次数大于 free或delete 时,会产生内存泄漏;需要‍防止多次重复free或者delete,当malloc或new 次数小于free或delete时,程序有可能会崩溃。6、使用malloc或new分配内存后,需要初始化,同时在使用时注意不要超过分配的内存大小空间。7、在哪个函数里面进行的 malloc或new ,就在哪个函数里面 free或delete,不要跨函数去释放动态的内存空间。8、不要将局部指针变量,局部引用变量或局部数组作为函数的返回值。9、使用数组时一定要注意定义的数组大小,防止数组越界;或者在定义数组时可以不定义数组长度,即int a[]。10、在定义有指针操作相关的函数时必须指定长度信息,即void fun(char* p, char len)。

BTW:
最后根据以上的讨论,再结合以下网友的总结,我们可以更好的理解下野指针在实际程序中的危害:

    a、指向不可访问(操作系统不允许访问的敏感地址,譬如内核空间)的地址,结果是触发段错误,这种算是最好的情况了。b、指向一个可用的、而且没什么特别意义的空间(譬如我们曾经使用过但是已经不用的栈空间或堆空间),这时候程序运行不会出错,也不会对当前程序造成损害,这种情况下会掩盖你的程序错误,让你以为程序没问题,其实是有问题的。

c、指向了一个可用的空间,而且这个空间其实在程序中正在被使用(譬如说是程序的一个变量x),那么野指针的解引用就会刚好修改这个变量x的值,导致这个变量莫名其妙的被改变,程序出现离奇的错误。一般最终都会导致程序崩溃,或者数据被损害。这种危害是最大的。

shp文件的可视化与编辑相关推荐

  1. 程序编辑SHP文件并应用更改到数据源

    在上一篇Blog中峻祁连介绍了在Map 3D中通过程序删除图层及数据源的方法,并且卖了个关子,这个方法还有另外一个妙用,今天就简单介绍一下.对数据源的编辑估计是Map 3D开发中最常见的功能了,包括对 ...

  2. shp文件纯前端的上传、解析、编辑、下载

    本文主要讲述一种体量较小的shp文件纯前端的上传.解析.编辑.下载的技术流程,适用于要素量少的shp文件修改操作. 准备工作 下载一下几个包,详细用法请见结尾参考. npm install file- ...

  3. arcgis中编码方式改变引起的shp文件乱码、字符截断问题处理

    arcgis中编码方式改变引起的shp文件乱码.字符截断问题处理 我们有时候使用ArcGIS读取shp文件的时候,打开属性表后,属性值存在中文乱码的情况,或字段项存在长度缩减的情况,这都是使用不同版本 ...

  4. MapGIS转Shp文件的单位问题

    MapGIS转Shp文件的单位问题 原文:MapGIS转Shp文件的单位问题 在MapGIS浏览查看一下数据,各种不习惯:用mapgis自带的转shp功能,属性表会出错:利用名为map2shp的试用版 ...

  5. arcgis根据矢量范围裁取tif影像(栅格数据)、批量合并shp文件、根据矢量范围裁取区域内的矢量,输出地理坐标系

    选取研究区域,作图美观. 这是最初的矢量文件,现在切割得到了云贵川地区的矢量文件,通过直接编辑最初的矢量文件. 现在要从上图切出云贵川区域. 打开对话框后输入影像和裁剪的区域,如果只需要裁剪的矢量区域 ...

  6. Geotools之“Hello World”——打开本地shp文件并显示

    概述:从本节开始,博文中会陆陆续续更新一些有关geotools相关的文章.本节讲述的是geotools的开胃菜,打开本地shp文件,并在窗口中显示. 引言:geotools简介. Geotools是J ...

  7. osm服务器 显示乱码,怎样获得osm上的行政区划shp文件

    2018.4.18 :刚刚发现我这里的wifi(电信的宽带)打不开下面的其中几个网站,需要使用网络工具才行.  但是用手机流量(联通)是可以直接打开的. 2018.1.25 :方法二的网站又恢复了. ...

  8. AutoCAD Map 3D对ArcGIS shp文件的操作详解!

    在之前的一篇推文中,介绍了用AutoCAD Map 3D将多段线转换为shp格式线或面文件,实际上,AutoCAD Map 3D作为CAD和GIS的桥梁,它对GIS数据格式的操作远不止这些. 例如:A ...

  9. C#不用ArcEngine,生成Shp文件(五)---------读取.shx文件和生成.shx文件

    这一篇来写一下.shx文件的读取跟生成.测试数据下载地址为:http://download.csdn.net/detail/gis0911178/9650967 在第一篇时候有介绍. 索引文件(.sh ...

最新文章

  1. linux双机脚本pkg如何生效,linux里命令pkg config工具的使用
  2. 正值实系数多项式函数所对应的导数累加和是否非负?
  3. 百度链接提交-主动推送Python版
  4. UVA 11478 Halum (差分约束)
  5. 使用CFree调用Win32 LoadLibrary 简单示例
  6. Linux gdb 破解软件密码
  7. C/C++ 位操作 总结
  8. [HNOI2010]公交线路
  9. 堡垒机CrazyEye安装脚本
  10. html5绘制矩形动画,HTML5下绘制矩形教程
  11. linux缓冲区攻击实验报告,linux 下缓冲区溢出攻击原理及示例
  12. asp与php对比,ASP和PHP文件操作速度的对比
  13. DDC 显示器数据通道
  14. 在linux下使用360随身wifi 2 | 李凡希的blog,在Linux下使用“360随身WiFi 2” | 李凡希的Blog...
  15. 步步为营——局域网调试NAS软路由“PVE+爱快+lede+黑群晖硬盘直通”并移植到宽带网(超详细,上篇)
  16. 仿真软件scaner studio上手基础操作(一)
  17. 让你的桌面腾飞吧(OpenSolaris2008.05 + VirtualBox + WinXP)
  18. 程序员在面试时,如何回答未来规划方面的问题
  19. Unity射击游戏发射子弹的方法和提升流畅性的小技巧
  20. keras保存历史准确率与loss值

热门文章

  1. 5.AVStream和AVCodecParameters
  2. 携程ajax,Python爬虫实战之爬取携程评论
  3. python数据库-2
  4. 自动计数报警器c语言程序,计数报警器电路设计方案汇总(多款模拟电路设计原理图详解)...
  5. 单片机 中断秒表 c语言程序,51单片机秒表C程序
  6. 在线机器学习算法及其伪代码
  7. 图卷积神经网络(GCN)
  8. RUA!ERROR!
  9. AI路径查找器如何使用
  10. Linux内核源码介绍