user-0 提问: 数据结构 数制转换问题

回复:
user: user-1
content: 引用 14 楼 u010703975 的回复:[quote=引用 13 楼 zhangxiangDavaid 的回复:] 10进制转8进制：  #include<stdio.h> #include<stdlib.h> typedef struct Node { 	int Data; 	struct Node *Next; } LinkStack; LinkStack *CreateStack() { 	LinkStack *S; 	S = (LinkStack *)malloc(sizeof(LinkStack)); 	S->Next = NULL; 	return S; } int isEmpty(LinkStack *S) { 	return (S->Next == NULL);  //若为空 返回1 } LinkStack *Push(LinkStack *S, int item) { 	LinkStack *TempCell; 	TempCell = (LinkStack *)malloc(sizeof(LinkStack)); 	TempCell->Data = item; 	TempCell->Next = S->Next; 	S->Next = TempCell; 	//free(TempCell);    //这句话error } int Pop(LinkStack *S) { 	LinkStack *FirstCell; 	int TopElem; 	if (isEmpty(S)) { 		printf("堆栈空\n"); 		return 0; 	} 	else { 		FirstCell = S->Next; 		S->Next = FirstCell->Next; 		TopElem = FirstCell->Data; 		free(FirstCell); 		return TopElem; 	} } void conversion() { 	LinkStack *s; 	int n; 	int item; 	s = CreateStack(); 	scanf("%d", &n); 	while (n) { 		Push(s, n % 8); 		n = n / 8; 	} 	while (!isEmpty(s)) { 		int item; 		item = Pop(s); 		printf("%d", item); 	} } int main(){ 	conversion(); 	return 0; }  为啥第一个free就错了 第二个free就可以呢[/quote] 在push的时候，会创建一个新的节点，添加到栈顶后，当然不可以释放掉。否则白搭。 在pop的时候，一旦获取了它的data域后，理应释放掉，否则，内存泄露。

user: user-2
content: 引用 2 楼 u010703975 的回复:[quote=引用 1 楼 brookmill 的回复:] // 把这一行删掉   free(TempCell); 删了之后 可以运行 但是运行的结果不是我想要的了[/quote] 我试了几个数，结果好像没错。你的数据？

user: user-0
content: 引用 1 楼 brookmill 的回复:// 把这一行删掉   free(TempCell); 删了之后 可以运行 但是运行的结果不是我想要的了

user: user-2
content: // 把这一行删掉   free(TempCell);

user: user-1
content: 10进制转8进制：  #include<stdio.h> #include<stdlib.h> typedef struct Node { 	int Data; 	struct Node *Next; } LinkStack; LinkStack *CreateStack() { 	LinkStack *S; 	S = (LinkStack *)malloc(sizeof(LinkStack)); 	S->Next = NULL; 	return S; } int isEmpty(LinkStack *S) { 	return (S->Next == NULL);  //若为空 返回1 } LinkStack *Push(LinkStack *S, int item) { 	LinkStack *TempCell; 	TempCell = (LinkStack *)malloc(sizeof(LinkStack)); 	TempCell->Data = item; 	TempCell->Next = S->Next; 	S->Next = TempCell; 	//free(TempCell);    //这句话error } int Pop(LinkStack *S) { 	LinkStack *FirstCell; 	int TopElem; 	if (isEmpty(S)) { 		printf("堆栈空\n"); 		return 0; 	} 	else { 		FirstCell = S->Next; 		S->Next = FirstCell->Next; 		TopElem = FirstCell->Data; 		free(FirstCell); 		return TopElem; 	} } void conversion() { 	LinkStack *s; 	int n; 	int item; 	s = CreateStack(); 	scanf("%d", &n); 	while (n) { 		Push(s, n % 8); 		n = n / 8; 	} 	while (!isEmpty(s)) { 		int item; 		item = Pop(s); 		printf("%d", item); 	} } int main(){ 	conversion(); 	return 0; }

user: user-0
content: 早上起来看 发现我删错了 我一开始把FirstCell删了 手残了

user: user-2
content: 引用 15 楼 u010703975 的回复:那为啥在Push函数里free掉临时的空间会报错 而在Pop函数里free掉临时的空间就可以了呢。 改怎么理解呢 因为Push之后还会继续用TempCell的内存，而Pop之后就不再使用FirstCell的内存了。  简单的说，这样的代码都是很可疑的： x = y; free(y); 而这种可能就是正确的 a = y->a; b = y->b; free(y);

user: user-2
content: 引用 10 楼 u010703975 的回复:现在都删掉了 运行正常 那么现在又多了个问题 临时stack空间在最后不是要free掉吗 malloc得到的内存最后需要free，这是毫无疑问的，但是应该是用完之后才释放，而且free之后就不应该再用了。 现在的问题是，从楼主描述的现象来看，free的早了，free之后又使用了。等到conversion这个函数结束之前把所有的都free掉应该就没问题了。 free(TempCell)是明显的错误，但是free(FirstCell)应该是正确的，因为从代码来看这个free之后就没再用FirstCell的内容，而且我用gcc和vs2013运行也没出错。 很好奇楼主用的什么编译器

user: user-0
content: 引用 7 楼 brookmill 的回复:[quote=引用 4 楼 u010703975 的回复:] [quote=引用 3 楼 brookmill 的回复:] [quote=引用 2 楼 u010703975 的回复:] [quote=引用 1 楼 brookmill 的回复:] // 把这一行删掉   free(TempCell); 删了之后 可以运行 但是运行的结果不是我想要的了[/quote] 我试了几个数，结果好像没错。你的数据？[/quote]  1348 -572662307 而且输出之后 弹出程序有错误  [/quote] -572662307 = 0xDDDDDDDD 我查了一下，据说有些运行环境会把free之后的堆内存用0xdd填充。 你确定把那个free(TempCell)删掉了？ 还可以试试把另一个free(FirstCell)也删掉，看看运行的结果有没有变化。 [/quote]  现在都删掉了 运行正常 那么现在又多了个问题 临时stack空间在最后不是要free掉吗

user: user-0
content: 引用 8 楼 user-3 的回复:lz是不是搞错了free的用法？ 恩恩是的 发现对free的用法有错误

user: user-0
content: 引用 11 楼 brookmill 的回复:[quote=引用 10 楼 u010703975 的回复:] 现在都删掉了 运行正常 那么现在又多了个问题 临时stack空间在最后不是要free掉吗 malloc得到的内存最后需要free，这是毫无疑问的，但是应该是用完之后才释放，而且free之后就不应该再用了。 现在的问题是，从楼主描述的现象来看，free的早了，free之后又使用了。等到conversion这个函数结束之前把所有的都free掉应该就没问题了。 free(TempCell)是明显的错误，但是free(FirstCell)应该是正确的，因为从代码来看这个free之后就没再用FirstCell的内容，而且我用gcc和vs2013运行也没出错。 很好奇楼主用的什么编译器[/quote]  那为啥在Push函数里free掉临时的空间会报错 而在Pop函数里free掉临时的空间就可以了呢。 改怎么理解呢

user: user-0
content: 引用 13 楼 zhangxiangDavaid 的回复:10进制转8进制：  #include<stdio.h> #include<stdlib.h> typedef struct Node { 	int Data; 	struct Node *Next; } LinkStack; LinkStack *CreateStack() { 	LinkStack *S; 	S = (LinkStack *)malloc(sizeof(LinkStack)); 	S->Next = NULL; 	return S; } int isEmpty(LinkStack *S) { 	return (S->Next == NULL);  //若为空 返回1 } LinkStack *Push(LinkStack *S, int item) { 	LinkStack *TempCell; 	TempCell = (LinkStack *)malloc(sizeof(LinkStack)); 	TempCell->Data = item; 	TempCell->Next = S->Next; 	S->Next = TempCell; 	//free(TempCell);    //这句话error } int Pop(LinkStack *S) { 	LinkStack *FirstCell; 	int TopElem; 	if (isEmpty(S)) { 		printf("堆栈空\n"); 		return 0; 	} 	else { 		FirstCell = S->Next; 		S->Next = FirstCell->Next; 		TopElem = FirstCell->Data; 		free(FirstCell); 		return TopElem; 	} } void conversion() { 	LinkStack *s; 	int n; 	int item; 	s = CreateStack(); 	scanf("%d", &n); 	while (n) { 		Push(s, n % 8); 		n = n / 8; 	} 	while (!isEmpty(s)) { 		int item; 		item = Pop(s); 		printf("%d", item); 	} } int main(){ 	conversion(); 	return 0; }  为啥第一个free就错了 第二个free就可以呢

user: user-3
content: lz是不是搞错了free的用法？

user: user-2
content: 引用 4 楼 u010703975 的回复:[quote=引用 3 楼 brookmill 的回复:] [quote=引用 2 楼 u010703975 的回复:] [quote=引用 1 楼 brookmill 的回复:] // 把这一行删掉   free(TempCell); 删了之后 可以运行 但是运行的结果不是我想要的了[/quote] 我试了几个数，结果好像没错。你的数据？[/quote]  1348 -572662307 而且输出之后 弹出程序有错误  [/quote] -572662307 = 0xDDDDDDDD 我查了一下，据说有些运行环境会把free之后的堆内存用0xdd填充。 你确定把那个free(TempCell)删掉了？ 还可以试试把另一个free(FirstCell)也删掉，看看运行的结果有没有变化。

user: user-2
content: 我用gcc和vs2013都试了，运行都没出错。而且我也看不出来代码里有什么大问题了。  几个建议： 1. conversion函数返回之前应该free(s); 2. Push这个函数声明了有返回值但是实际上没有，声明成void即可。 3. 每次调用malloc的时候都要判断一下返回值是否NULL 4. 函数参数里如果有指针，首先应该判断它是否NULL  这些都只是属于良好的编程习惯，在你这个小程序里面应该都不会造成什么问题的。

user: user-2
content: 我运行结果没错： $ ./a.exe 1348 2504 可能是有些内存越界之类的问题，我再看看

user: user-0
content: 引用 3 楼 brookmill 的回复:[quote=引用 2 楼 u010703975 的回复:] [quote=引用 1 楼 brookmill 的回复:] // 把这一行删掉   free(TempCell); 删了之后 可以运行 但是运行的结果不是我想要的了[/quote] 我试了几个数，结果好像没错。你的数据？[/quote]  1348 -572662307 而且输出之后 弹出程序有错误