30了。我要怎么办,老了。人就像一头小毛驴,方向都是牵着的人定的。

这个项目从去年开始的,一个手机游戏,当时接这个项目的时候其实没有太多考虑,我一向都喜欢打肿脸充胖子的,好面子,人家找上门来,不能不给面子。

如果是我自己想的一个创意,估计做不下去的时候随手就放弃了,一点都不伤心,最多过几年后同样一个创意出现之后,懊悔曾经没有坚持到底过。或者最后成为一个面目全非的四不像。历史上的那些想法无出这些框架。但是这是答应别人的事情,没奈何开始了这段痛苦的过程。

这几年其实游戏玩的多,实际上就没有开发过几个,这些技术早就放下很早了。而且没在企业里呆过太长的时间,编码很不规范,这些恶果很快就显现了出来。刚开始的几个月写啊写啊,然后几万行代码出来了。等到过几天修改错误,编译成功了。还没开心的出来,痛苦的事情到了。

首先进去就是个死循环。一点反应没有。这是什么原因呢,时间长了,我也忘了。反正很快解决了。

接着刷的一下,程序崩溃了。这是毛原因呢。挂上ollydbg,我跟我跟,原来,参数传递不正确,本来三个参数,结果仅传过去两个。然后怅然若失,重新修订代码,对所有外部函数做声明。

麻烦事还没完。人家明明是初到江湖,没有菜刀的,为什么我这里扛着一把刀呢。我再跟,原来那里定义的是byte,我这个文件extern的时候没加,直接一个extern 变量,默认是int罢,本来读一个字节肯定是0,这里读4个字节,很难是0了。

然后再次修订源代码,确保extern后面都有定义。

然后提示变量为null,跟了一下啊,明明是正常有值的,咋么就忽然消失了呢,痛苦啊痛苦啊,一怒之下推开,过几天还要乖乖坐下来工作。跟了几下发现还是声明不对。定义的时候是数组的形式,我extern的是指针,谁告诉我数组和定义差不多了呢。这差的远了三百里了。

另外数值符号,一个正byte乘上一个正byte,变成了负数。然后再去读数组,不知道读哪里去了。

前面定义了一个一维数组,后来用了一个二维数组指针赋值,内存跑远了。然后检查所有数组。

再次修订源代码,这可是10万行的大项目啊,我就这么一个人,修啊补啊,痛苦不愿回首。

我终于下狠心要规范代码写作,因为这带来的后果的修订远长于开发时节约的时间了。

还有一个地方,就是编码,现在的开发一定要坚持使用unicode编码。我用vc6.0,使用unicode定义变量怕麻烦,所以使用了gb2312。然而资源采用了UTF8格式。本来是utf8-unicode就可以完成所有工作。而我变成这样子utf8-unicode-gb2312-unicode-gb2312-unicode,多出了许多转化过程不说,也是造成许多错误根源。

我本以为这些已经够了,然而以后多次围绕我的梦魇来了。

内存问题,一个挥之不去的恶梦。我终于知道为什么要开发托管代码了。怀念java和.net。没有亲身体验过,真是很难想象这些理由。所以一些让人崇拜的大牛其经历也想必是非一般的坎坷。

内存上的错误主要有三种。尽管都是老生常谈的东西了。不过痛苦之后再来看感觉又是另外一番滋味。

1)多次释放和不正确释放

以前释放完之后,不把指针设为null,变成了野指针。然后又用啊,又释放啊。错误发生了。

因为内存的随处分配,所有最后专门有个步骤释放内存,释放完了发现运行不正确,一个结构中的数据面目全非。又是痛苦的跟踪检查,发现有处指针指向栈区,这个指针又被七指八指,最后看不出来指向堆栈,然后这个指针释放,栈上的数据被破坏。

2)内存泄漏

一般来说谁分配谁释放的准则。但是写代码的时候没有注意,随处分配,最后挨个跟踪指针,经常跟错。增加了许多时间。

3)内存越界

内存越界是痛苦中的痛苦。表现在错误的出现随机,某处越界可能很久之后才表现出来,找都找不到错误从哪里出来的,别的跟踪一下子代码大致能看出端倪,一般错误的出现就在错误附近。

一直看黑客教程栈溢出和堆溢出这么重视,等到自己编程的时候才发现原来是普遍性错误。

内存越界其内存的分配并不按照先后顺序分配,后分配的有可能在前面。内存越界造成的错误也是多种多样。简单的把另外一块内存冲了,有一次字符串连接空间分配小了,淹没了另外一个字符串,结果本来主角说的话从NPC口中说出来。

更复杂的错误也有。

一般用malloc分配的内存前面有4个字节的内存信息,越界淹没了这个信息,好一点的出现内存分配错误,运气差一点淹没的部分被重新利用,来分配其他东西了。

痛苦中一次次懊悔,如果当时充分考虑就好了。如果上天有重来一次的机会,我一定会认真写代码,整整洁洁标标准准,像印度人写的一样。

如今这个过程告一段落。终于能正常运行了。看到自己苦心栽培的东西茁壮成长,心里格外的高兴,看着鲜艳的五星红旗,小朋友的脸蛋像红彤彤的苹果。越是付出的多也有价值。所以恋爱的时候一定要让对方多付出,付出的越多越不会放弃。许多放不下的人都是这样想的。不甘心。

写这篇文字前,我又运行了一下程序,在vc环境下模拟器中运行,欣喜的发现程序完全没有问题,忽然跳出个对话框,vc崩溃了。


如果你想快速掌握编程,小编推荐我的C语言/C++编程学习基地【点击进入】!

都是学编程小伙伴们,带你入个门还是简简单单啦,一起学习,一起加油~

还有许多学习资料和视频,相信你会喜欢的!

涉及:编程入门、游戏编程、课程设计、黑客等等......

 

用 C 语言游戏编程开发!果然最担心的事又发生了!的更多相关文章

  1. Mac iOS Mac Watch 应用和游戏编程开发工具推荐

    今日分享「iOS / Mac / Watch 应用和游戏开发工具」推荐,这期专题主要为iOS开发者推荐一些优秀的设计和开发工具,这些工具包含移动原型的设计.程序的开发等,可以大大提高开发的效率!专题会 ...

  2. 【Visual C++】游戏编程学习笔记之三:游戏循环的使用

     本系列文章由@二货梦想家张程 所写,转载请注明出处. 本文章链接:http://blog.csdn.net/terence1212/article/details/44208419 作者:Zee ...

  3. Android程序中,内嵌ELF可执行文件-- Android开发C语言混合编程总结

    前言 都知道的,Android基于Linux系统,然后覆盖了一层由Java虚拟机为核心的壳系统.跟一般常见的Linux+Java系统不同的,是其中有对硬件驱动进行支持,以避开GPL开源协议限制的HAL ...

  4. java游戏开发杂谈 - 游戏编程浅析

    每个游戏,你所看到的它的一切,都是计算机画出来的! 地图是画出来,人物是画出来的,树木建筑是画出来的,菜单按钮是画出来的,滚动的文字.闪烁的图标.云雾烟火,都是画出来的. 游戏编程,所要做的,就是控制 ...

  5. 融云开发漫谈:你是否了解Go语言并发编程的第一要义?

    2007年诞生的Go语言,凭借其近C的执行性能和近解析型语言的开发效率,以及近乎完美的编译速度,席卷全球.Go语言相关书籍也如雨后春笋般涌现,前不久,一本名为<Go语言并发之道>的书籍被翻 ...

  6. 【编程开发】C语言中随机数rand使用注意事项

    [编程开发]C语言中随机数rand使用注意事项 标签: [编程开发] 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:随机数在编程开发中非常重要,以C语 ...

  7. go语言游戏服务端开发(一)——架构

    五邑隐侠,本名关健昌,12年游戏生涯. 本教程以Go语言为例.   网络游戏程序分为客户端和服务端.客户端负责图形渲染.交互和一些简单校验处理,服务端负责业务逻辑处理.数据存储. 我们开发一个游戏de ...

  8. 【python游戏编程之旅】第九篇---嗷大喵快跑小游戏开发实例

    本系列博客介绍以python+pygame库进行小游戏的开发.有写的不对之处还望各位海涵. 前几期博客我们一起学习了,pygame中的冲突检测技术以及一些常用的数据结构. 这次我们来一起做一个简单的酷 ...

  9. 【python游戏编程之旅】第八篇---pygame游戏开发常用数据结构

    本系列博客介绍以python+pygame库进行小游戏的开发.有写的不对之处还望各位海涵. 上一个博客我们一起学习了pygame中冲突检测技术:http://www.cnblogs.com/msxh/ ...

随机推荐

  1. IEDA使用Tomcat后控制台中文出现乱码

    如下图所示,Intellij IDEA显示中文为乱码, 根据Intellij IDEA控制台输出,Tomcat  Log出现乱码,因此可以将问题定位到Tomcat上,具体解决方法: 第一步:打开Tom ...

  2. 基于jQuery的鼠标悬停时放大图片的效果制作

    这是一个基于jQuery的效果,当鼠标在小图片上悬停时,会弹出一个大图,该大图会跟随鼠标的移动而移动.这个效果最初源于小敏同志的一个想法,刚开始做的时候只能实现弹出的图片是固定的,不能随鼠标移动,最后 ...

  3. seajs1.3.0源码解析之module依赖有序加载

    /** * The core of loader */ ;(function(seajs, util, config) { // 模块缓存 var cachedModules = {} // 接口修改 ...

  4. 自然常数e的含义

    e是一个重要的常数,但是它的直观含义却不像 π 那么明了.我们都知道,圆的周长与直径之比是一个常数,这个常数被称为圆周率,记作 π = 3.14159......可是e代表什么呢? e是“指数”(ex ...

  5. 【深入理解Linux内核架构】3.3 页表

    页表:用于建立用户进程空间的虚拟地址空间和系统物理内存(内存.页帧)之间的关联. 向每个进程提供一致的虚拟地址空间. 将虚拟内存页映射到物理内存,因而支持共享内存的实现. 可以在不增加物理内存的情况下 ...

  6. ASP.NET Core 3.x启动时运行异步任务(一)

    这是一个大的题目,需要用几篇文章来说清楚.这是第一篇.   一.前言 在我们的项目中,有时候我们需要在应用程序启动前执行一些一次性的逻辑.比方说:验证配置的正确性.填充缓存.或者运行数据库清理/迁移等 ...

  7. Node.js使用npm安装模块太慢,解决办法

    转自 淘宝 npm 地址: http://npm.taobao.org/ 如何使用 有很多方法来配置npm的registry地址,下面根据不同情境列出几种比较常用的方法.以淘宝npm镜像举例: 1.临 ...

  8. Linux实战(9):Docker一键搭建kms服务

    server端 docker pull luodaoyi/kms-server docker run -itd -p 1688:1688 --name kms luodaoyi/kms-server ...

  9. 01.vue数据绑定

    Vue特点 渐进式: 渐进, 可以理解成一步一步的. 在使用Vue的时候, 我们不需要把整个Vue框架的东西都用上, 可以一步一步的根据需要慢慢的替换之前的代码. 自底向上逐层应用: 由底层开始, 把 ...

  10. manacher(马拉车算法)

    Manacher(马拉车算法) 序言 mannacher 是一种在 O(n)时间内求出最长回文串的算法 我们用暴力求解最长回文串长度的时间复杂度为O(n3) 很明显,这个时间复杂度我们接受不了,这时候 ...