win&linux 在同一个问题上的不同表现
?我在写单链表的逆转时,遇到了一些很有意思的事情。
?
同样一段代码,在win和linux下是完全两种不同的结果。
#include <stdio.h>#include <stdlib.h>#include <string.h>#define SIZE 64typedef struct info{ int num; char msg[SIZE]; struct info *next;}Info;typedef struct vec{ Info *element; struct vec *next;}Vector;const unsigned int SIZE_INFO = sizeof(Info);Info *createInfo(Info *header, int nums){ int num = 0; char *msg = "hello msg"; Info *tmp = NULL; Info *h2 = header; int i = 0; #define NUM 4 char strNum[NUM]; memset(strNum, 0x00, NUM); header->num = 0; for (i = 0; i < nums; i++) { tmp = (Info *)calloc(SIZE_INFO, 1); tmp->num = num++; strcpy(tmp->msg, msg); sprintf(strNum, ": %d", tmp->num); strcat(tmp->msg, strNum); h2->next = tmp; h2 = h2->next; h2->next = NULL; header->num++;memset(strNum, 0x00, NUM); } return header;}void deleteInfo(Info *header){ Info *tmp = header->next; Info *tmp2 = NULL; while(tmp != NULL) { tmp2 = tmp->next; free(tmp); tmp = tmp2; } header->next = NULL;}void printInfo(const Info *header){ Info *tmp = header->next; while (tmp != NULL) { printf("[num]->%d\t[msg]->%s\n", tmp->num, tmp->msg); tmp = tmp->next; } printf("**END**\n");}Info *reserve(Info *header){ Info *tail = NULL; Info *tmp = NULL; Vector *v = (Vector *)calloc(sizeof(Vector), 1); v->next = NULL; Vector *vTmp = NULL; tmp = header; while(tmp->next != NULL) { tmp = tmp->next; vTmp = (Vector *)calloc(sizeof(Vector), 1); vTmp->element = tmp; if (v->next == NULL) { v->next = vTmp; vTmp->next = NULL; } else { vTmp->next = v->next; v->next = vTmp; } } vTmp = v; tmp = header; while (vTmp->next != NULL) { tmp->next = vTmp->next->element; vTmp = vTmp->next; tmp = tmp->next; } tmp->next = NULL; vTmp = v->next; Vector *vTmp2 = NULL; while (vTmp != NULL) { vTmp2 = vTmp->next; free(vTmp); vTmp = vTmp2; } vTmp = NULL; free(v); v = NULL; return header;}void re(Info *header, Info *cur){ if (cur->next == NULL) { header->next = cur; cur->next = NULL; } else { Info *a = NULL; Info *b = NULL; if (header == cur) { a = cur->next; b = a->next; } else { a = cur; b = cur->next; } if (b != NULL) { re(header, b); b->next = a; if (cur == header) a->next = NULL; } }}int main(int argc, char *argv[]){ Info *header = (Info *)calloc(SIZE_INFO, 1); int num; if (argc == 1) num = 11; else sscanf(argv[1], "%d", &num); header = createInfo(header, num); printInfo(header);// header = reserve(header);// printInfo(header); //reserve3(header, header); re(header, header); printInfo(header); deleteInfo(header); free(header); header = NULL; // linux 下注释掉 //system("pause"); return EXIT_SUCCESS;}
?
?
这里有个很好玩的东西,开始我是在linux下运行的,当我把链表建的超过10时,得到的数据量就会非常的大,比如说11时,就会得到100个数据,111就会得到10000个数据。
?
然而我到winxp下一运行就报错了:
?
[Run-Time Check Failure #2 - Stack around the variable 'strNum' was corrupted.]
?
确实问题就出现在,createInfo方法里的strNum这个字符数组的大小的设定上。
在使用:sprintf(strNum, ": %d", tmp->num);
时,出现了一个问题。开始如果设定的链表数是1位数时,那么此处strNum中前3个字节有 值,第四个字节可以正常的以’\0’结尾,但是在存储10时,它在转换成字符之后,就应该是两个单独的字符,应此就占了2字节。此时strNum总共的4个字节就都用完了,那么正常的字符串结尾的’\0’就不见了,此时就出现了win和linux下两者不同的出错处理。此处,linux下的给我创建100个数据,我就表示很怀疑了,这是为什么呢?看来win的编译器还是挺严格的,这里只是说,strNum的堆栈被破坏了,但是strNum中的数据是对的,就给报了个run-time error,而不会像linux下一样,竟然跑出个匪夷所思的结果。不知道是不是我的gcc版本太旧了?
?
还有一个有意思的地方是:win在报这个run-time error时,是在函数createInfo结束时,即createInfo退栈时出的错,也就是说在释放strNum的内存时发现strNum的stack was corrupted?
?
当然,如果在createInfo中将strNum的大小设的足够大的话,这个问题也是不会出现的。
?
附上linux下创建22个数据的结果:
?
$ ./Info3 22[num]->0 [msg]->hello msg: 0[num]->1 [msg]->hello msg: 1[num]->2 [msg]->hello msg: 2[num]->3 [msg]->hello msg: 3[num]->4 [msg]->hello msg: 4[num]->5 [msg]->hello msg: 5[num]->6 [msg]->hello msg: 6[num]->7 [msg]->hello msg: 7[num]->8 [msg]->hello msg: 8[num]->9 [msg]->hello msg: 9[num]->10 [msg]->hello msg: 10[num]->11 [msg]->hello msg: 11[num]->12 [msg]->hello msg: 12[num]->13 [msg]->hello msg: 13[num]->14 [msg]->hello msg: 14[num]->15 [msg]->hello msg: 15[num]->16 [msg]->hello msg: 16[num]->17 [msg]->hello msg: 17[num]->18 [msg]->hello msg: 18[num]->19 [msg]->hello msg: 19[num]->20 [msg]->hello msg: 20[num]->21 [msg]->hello msg: 21[num]->22 [msg]->hello msg: 22[num]->23 [msg]->hello msg: 23[num]->24 [msg]->hello msg: 24[num]->25 [msg]->hello msg: 25[num]->26 [msg]->hello msg: 26[num]->27 [msg]->hello msg: 27[num]->28 [msg]->hello msg: 28[num]->29 [msg]->hello msg: 29[num]->30 [msg]->hello msg: 30[num]->31 [msg]->hello msg: 31[num]->32 [msg]->hello msg: 32[num]->33 [msg]->hello msg: 33[num]->34 [msg]->hello msg: 34[num]->35 [msg]->hello msg: 35[num]->36 [msg]->hello msg: 36[num]->37 [msg]->hello msg: 37[num]->38 [msg]->hello msg: 38[num]->39 [msg]->hello msg: 39[num]->40 [msg]->hello msg: 40[num]->41 [msg]->hello msg: 41[num]->42 [msg]->hello msg: 42[num]->43 [msg]->hello msg: 43[num]->44 [msg]->hello msg: 44[num]->45 [msg]->hello msg: 45[num]->46 [msg]->hello msg: 46[num]->47 [msg]->hello msg: 47[num]->48 [msg]->hello msg: 48[num]->49 [msg]->hello msg: 49[num]->50 [msg]->hello msg: 50[num]->51 [msg]->hello msg: 51[num]->52 [msg]->hello msg: 52[num]->53 [msg]->hello msg: 53[num]->54 [msg]->hello msg: 54[num]->55 [msg]->hello msg: 55[num]->56 [msg]->hello msg: 56[num]->57 [msg]->hello msg: 57[num]->58 [msg]->hello msg: 58[num]->59 [msg]->hello msg: 59[num]->60 [msg]->hello msg: 60[num]->61 [msg]->hello msg: 61[num]->62 [msg]->hello msg: 62[num]->63 [msg]->hello msg: 63[num]->64 [msg]->hello msg: 64[num]->65 [msg]->hello msg: 65[num]->66 [msg]->hello msg: 66[num]->67 [msg]->hello msg: 67[num]->68 [msg]->hello msg: 68[num]->69 [msg]->hello msg: 69[num]->70 [msg]->hello msg: 70[num]->71 [msg]->hello msg: 71[num]->72 [msg]->hello msg: 72[num]->73 [msg]->hello msg: 73[num]->74 [msg]->hello msg: 74[num]->75 [msg]->hello msg: 75[num]->76 [msg]->hello msg: 76[num]->77 [msg]->hello msg: 77[num]->78 [msg]->hello msg: 78[num]->79 [msg]->hello msg: 79[num]->80 [msg]->hello msg: 80[num]->81 [msg]->hello msg: 81[num]->82 [msg]->hello msg: 82[num]->83 [msg]->hello msg: 83[num]->84 [msg]->hello msg: 84[num]->85 [msg]->hello msg: 85[num]->86 [msg]->hello msg: 86[num]->87 [msg]->hello msg: 87[num]->88 [msg]->hello msg: 88[num]->89 [msg]->hello msg: 89[num]->90 [msg]->hello msg: 90[num]->91 [msg]->hello msg: 91[num]->92 [msg]->hello msg: 92[num]->93 [msg]->hello msg: 93[num]->94 [msg]->hello msg: 94[num]->95 [msg]->hello msg: 95[num]->96 [msg]->hello msg: 96[num]->97 [msg]->hello msg: 97[num]->98 [msg]->hello msg: 98[num]->99 [msg]->hello msg: 99[num]->100 [msg]->hello msg: 100**END**[num]->100 [msg]->hello msg: 100[num]->99 [msg]->hello msg: 99[num]->98 [msg]->hello msg: 98[num]->97 [msg]->hello msg: 97[num]->96 [msg]->hello msg: 96[num]->95 [msg]->hello msg: 95[num]->94 [msg]->hello msg: 94[num]->93 [msg]->hello msg: 93[num]->92 [msg]->hello msg: 92[num]->91 [msg]->hello msg: 91[num]->90 [msg]->hello msg: 90[num]->89 [msg]->hello msg: 89[num]->88 [msg]->hello msg: 88[num]->87 [msg]->hello msg: 87[num]->86 [msg]->hello msg: 86[num]->85 [msg]->hello msg: 85[num]->84 [msg]->hello msg: 84[num]->83 [msg]->hello msg: 83[num]->82 [msg]->hello msg: 82[num]->81 [msg]->hello msg: 81[num]->80 [msg]->hello msg: 80[num]->79 [msg]->hello msg: 79[num]->78 [msg]->hello msg: 78[num]->77 [msg]->hello msg: 77[num]->76 [msg]->hello msg: 76[num]->75 [msg]->hello msg: 75[num]->74 [msg]->hello msg: 74[num]->73 [msg]->hello msg: 73[num]->72 [msg]->hello msg: 72[num]->71 [msg]->hello msg: 71[num]->70 [msg]->hello msg: 70[num]->69 [msg]->hello msg: 69[num]->68 [msg]->hello msg: 68[num]->67 [msg]->hello msg: 67[num]->66 [msg]->hello msg: 66[num]->65 [msg]->hello msg: 65[num]->64 [msg]->hello msg: 64[num]->63 [msg]->hello msg: 63[num]->62 [msg]->hello msg: 62[num]->61 [msg]->hello msg: 61[num]->60 [msg]->hello msg: 60[num]->59 [msg]->hello msg: 59[num]->58 [msg]->hello msg: 58[num]->57 [msg]->hello msg: 57[num]->56 [msg]->hello msg: 56[num]->55 [msg]->hello msg: 55[num]->54 [msg]->hello msg: 54[num]->53 [msg]->hello msg: 53[num]->52 [msg]->hello msg: 52[num]->51 [msg]->hello msg: 51[num]->50 [msg]->hello msg: 50[num]->49 [msg]->hello msg: 49[num]->48 [msg]->hello msg: 48[num]->47 [msg]->hello msg: 47[num]->46 [msg]->hello msg: 46[num]->45 [msg]->hello msg: 45[num]->44 [msg]->hello msg: 44[num]->43 [msg]->hello msg: 43[num]->42 [msg]->hello msg: 42[num]->41 [msg]->hello msg: 41[num]->40 [msg]->hello msg: 40[num]->39 [msg]->hello msg: 39[num]->38 [msg]->hello msg: 38[num]->37 [msg]->hello msg: 37[num]->36 [msg]->hello msg: 36[num]->35 [msg]->hello msg: 35[num]->34 [msg]->hello msg: 34[num]->33 [msg]->hello msg: 33[num]->32 [msg]->hello msg: 32[num]->31 [msg]->hello msg: 31[num]->30 [msg]->hello msg: 30[num]->29 [msg]->hello msg: 29[num]->28 [msg]->hello msg: 28[num]->27 [msg]->hello msg: 27[num]->26 [msg]->hello msg: 26[num]->25 [msg]->hello msg: 25[num]->24 [msg]->hello msg: 24[num]->23 [msg]->hello msg: 23[num]->22 [msg]->hello msg: 22[num]->21 [msg]->hello msg: 21[num]->20 [msg]->hello msg: 20[num]->19 [msg]->hello msg: 19[num]->18 [msg]->hello msg: 18[num]->17 [msg]->hello msg: 17[num]->16 [msg]->hello msg: 16[num]->15 [msg]->hello msg: 15[num]->14 [msg]->hello msg: 14[num]->13 [msg]->hello msg: 13[num]->12 [msg]->hello msg: 12[num]->11 [msg]->hello msg: 11[num]->10 [msg]->hello msg: 10[num]->9 [msg]->hello msg: 9[num]->8 [msg]->hello msg: 8[num]->7 [msg]->hello msg: 7[num]->6 [msg]->hello msg: 6[num]->5 [msg]->hello msg: 5[num]->4 [msg]->hello msg: 4[num]->3 [msg]->hello msg: 3[num]->2 [msg]->hello msg: 2[num]->1 [msg]->hello msg: 1[num]->0 [msg]->hello msg: 0**END**
?
?
这个结果是不是非常的牛叉。
?
附上linux&gcc相关信息:
?
1.$ cat /proc/version 2.Linux version 2.4.20-8 (bhcompile@porky.devel.redhat.com) (gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) #1 Thu Mar 13 17:54:28 EST 2003
?
End
?
?
?
?
?