|
我在写单链表的逆转时,遇到了一些很有意思的事情。
同样一段代码,在
win
和
linux
下是完全两种不同的结果。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 64
typedef 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
|
|
|