user-0 提问: 运行时程序直接停止工作

回复:
user: user-1
content: 修改如下：  #include <stdlib.h> #include <malloc.h> #include <time.h> #include <stdio.h> #include <math.h> typedef struct person { 	int age; 	int gene[32]; 	int Tc; 	struct person *link; }per; per *creat() { 	per *head, *p; 	int n = 0, i, j, k; 	//srand((unsigned)time(NULL));   //只需设置一次 	head= (per*)malloc(sizeof(per));   //头节点 	p = head; 	for (i = 0; i < 1000; i++) 	{ 		p->link = (per *)malloc(sizeof(per)); 		p = p->link; 		p->age = rand() % 32 + 1;//随机生成年龄1-32 		p->Tc = 0; 		for (j = 0; j < p->age; j++) 		{ 			//随机生成基因 			if (1 == (p->gene[j] = rand() % 2)) p->Tc++; //统计致病基因数量 		} 	} 	p->link = NULL; 	return(head); } int main() { 	per *p, *q, *head, *p1, *p2; 	FILE *fp; 	int x1, x2, x3, m, t, l, x, r; 	srand((unsigned)time(NULL)); 	//p = creat();     head = creat(); 	//head = p; 	fp = fopen("penna.txt", "w"); 	for (t = 0; t < 1000; t++)//1000个时间步   //不明白为什么要有循环？ 	{ 		p = head; 		q = p->link; 		while (q) 		{ 			if (q->age >= 32 || q->Tc >= 2) //老死||病死 			{ 				p->link = q->link; 				free(q); 				q = p; 			} 			p = q; 			q = q->link; 		}  		p = head->link; 		l = 0; 		while (p)//统计存活个数 		{ 			l++, p = p->link; 		}  		if (l >= 100000) //判断是否超环境容量 		{ 			printf("all dead"); 			break; 		} 		x = ceil((float)l / 100000 * 1000);//计算死亡率 		p = head; 		q = p->link; 		//srand((unsigned)time(NULL)); 		while (q) 		{ 			r = rand() % 1000 + 1; 			if (r < x)//满足条件则当前个体死亡 			{ 				p->link = q->link; 				free(q); 				q = p; 			} 			p = q; 			q = q->link; 		} 		p = head; 		q = p->link; 		p1 = (per *)malloc(sizeof(per));  //头节点 		p1->link = NULL; 		p2 = p1; 		while (q) 		{ 			if (q->age >= 8) 			{ 				p2->link = (per *)malloc(sizeof(per));//新个体 				p2 = p2->link; 				p2->link = NULL; 				p2->age = q->age;//复制过程 				for (m = 0; m < q->age; m++) p2->gene[m] = q->gene[m]; 				x1 = rand() % q->age;//突变过程M=2 				x2 = rand() % q->age; 				p2->gene[x1] = (!q->gene[x1]); 				p2->gene[x2] = (!q->gene[x2]); 				//p2 = head; 				//while (p2->link != 0) p2 = p2->link;//找寻链表的末尾 				//p2->link = p1;//在链表末尾加上新个体 				//p1->link = NULL; 			} 			p = q; 			q = q->link; 		} 		//把新个体添到链表的末尾 		p->link = p1->link; 		free(p1);    //释放头节点  		p = head->link, x3 = 1; 		//srand((unsigned)time(NULL)); 		while (p) 		{ 			p->gene[p->age] = rand() % 2, p->age++; 			x3++, p = p->link; 		} 		fprintf(fp, "%d\n", x3); 	} 	fclose(fp); 	return 0; }

user: user-2
content: 引用 12 楼 qq_25720277 的回复:原谅我看不懂这么高深的C语言。。 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  不要企图依赖输出指针相关表达式...的值【比如printf("%p\n",...);或者cout<<...】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=(void *)(...);】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495

user: user-0
content: 请教一下我想把代码输入为 大家可以直接复制的那种样子，该怎么输入呢？

user: user-0
content: while(p->link!=NULL)  																					  { 																						  p->gene[p->age]=rand()%2,p->age++; 																						  x3++,p=p->link; 																					  } 																					  fprintf(fp,"%d\n",x3); 		  } 		                                                                               fclose(fp); } 我调试到最后这一小部分，出了acess violation的错误。查了资料，发现错误原因是访问了一块不再有效地内存，但我不知怎么改，求路过好心人指教，

user: user-0
content: 原谅我看不懂这么高深的C语言。。

user: user-3
content: 单步断点调试，肯定能找到问题

user: user-0
content: 还有就是，我反复检查我的程序并没有发现下标越界，而且在调试时经常出现找不到变量的提示。麻烦哪位路过大神解答一下下

user: user-0
content: ”写常量“是什么意思呢？

user: user-0
content: 我调试过了，但是还是不行。。

user: user-4
content: 凡事靠自己啊！一楼都解答了，剩下的自己找错啊！----我就是一个小白--路过此地！

user: user-2
content: 点一下带<>的图标， 【code=c】将代码插入在此【/code】

user: user-2
content: 引用 6 楼 qq_25720277 的回复:还有就是，我反复检查我的程序并没有发现下标越界，而且在调试时经常出现找不到变量的提示。麻烦哪位路过大神解答一下下 不要依赖调试环境，自己写日志调试。  有时不将“调用函数名字＋各参数值，进入函数后各参数值，中间变量值，退出函数前准备返回的值，返回函数到调用处后函数名字＋各参数值＋返回值”这些信息写日志到文件中是无论如何也发现不了问题在哪里的，包括捕获各种异常、写日志到屏幕、单步或设断点或生成core文件、……这些方法都不行！ 写日志到文件参考下面： #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <io.h> #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  _vsnprintf         vsnprintf #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef WIN32 void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;      if (NULL==pszFmt||0==pszFmt[0]) return;     _vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }         } else {             fclose(flog);         }     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} int main(int argc,char * argv[]) {     int i; #ifdef WIN32     InitializeCriticalSection(&cs_log); #else     pthread_mutex_init(&cs_log,NULL); #endif     for (i=0;i<10000;i++) {         Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);     } #ifdef WIN32     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_log); #endif     return 0; } //1-78行添加到你带main的.c或.cpp的那个文件的最前面 //81-85行添加到你的main函数开头 //89-93行添加到你的main函数结束前 //在要写LOG的地方仿照第87行的写法写LOG到文件MyLog1.log中

user: user-0
content: 谢谢，能具体一点吗

user: user-5
content: 内存溢出,下标越界,写常量等...