设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 2402|回复: 10
打印 上一主题 下一主题

[有事请教] C语言指针与内存分配问题

[复制链接]

Lv2.观梦者

梦石
0
星屑
491
在线时间
339 小时
注册时间
2010-12-15
帖子
926

开拓者

跳转到指定楼层
1
发表于 2011-7-18 18:17:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
本帖最后由 tamashii 于 2011-7-18 18:17 编辑

闲来没事用C写了一个链表玩玩,可是……编译成功了,一运行就卡死 - -
求C大师指教
编译环境:Win7 x64 & GCC
  1. #include <stdio.h>
  2. #include <memory.h>

  3. typedef struct _tagSTACK_ITEM {
  4.         struct _tagSTACK_ITEM *next;
  5.         int value;
  6. } STACK_ITEM;

  7. typedef struct _tagSTACK {
  8.         int length;
  9.         STACK_ITEM *top;
  10. } STACK;

  11. short CreateStack(STACK * ret_stack) {
  12.         STACK stack;
  13.         memset(&stack, 0, sizeof(STACK));
  14.         stack.length = 0;
  15.         stack.top = 0;
  16.         ret_stack = &stack;
  17.         return 1;
  18. }

  19. short CreateStackItem(int value, STACK_ITEM * ret_item) {
  20.         STACK_ITEM item;
  21.         memset(&item, 0, sizeof(STACK_ITEM));
  22.         item.value = value;
  23.         item.next = 0;
  24.         ret_item = &item;
  25.         return 1;
  26. }

  27. void StackPush(STACK *stack, int value) {
  28.         if (stack->top == 0) { /* if stack is empty, let the top of stack goto value. */
  29.                 STACK_ITEM *item;
  30.                 memset(item, 0, sizeof(STACK_ITEM));
  31.                 CreateStackItem(value, item);
  32.                 stack->top = item;
  33.         }
  34.         else { /* if not, insert a new node. */
  35.                 STACK_ITEM *item;
  36.                 CreateStackItem(value, item);
  37.                 item->next = stack->top;
  38.                 stack->top = item;
  39.         }
  40.         stack->length++;
  41. }

  42. int StackPop(STACK *stack, int *value) {
  43.         if (stack->length == 0) { /* if stack is null, then it will error. */
  44.                 *value = 0;
  45.                 return 0;
  46.         }
  47.         /* if not, pop a value. */
  48.         *value = stack->top->value;
  49.         /* move to next */
  50.         stack->top = stack->top->next;
  51.         stack->length--;
  52.         return 1;
  53. }

  54. int main() {
  55.         int i = 0;
  56.         int a = 0;
  57.         STACK * stack = 0;
  58.         CreateStack(stack);
  59.         StackPush(stack, 1);
  60.         StackPush(stack, 2);
  61.         StackPush(stack, 3);
  62.         StackPush(stack, 4);
  63.         StackPush(stack, 5);
  64.         for (i = 0; i < 5; i++) {
  65.                 if (StackPop(stack, &a)) {
  66.                         printf("%d\n", a);
  67.                 }
  68.                 else {
  69.                         printf("\aError! stack is empty! ");
  70.                         return -1;
  71.                 }
  72.         }
  73.         return 0;
  74. }
复制代码

Lv1.梦旅人

梦石
0
星屑
239
在线时间
2399 小时
注册时间
2008-4-11
帖子
12326

贵宾第6届短篇游戏比赛季军

2
发表于 2011-7-18 18:24:52 | 只看该作者
在每句前面都加一个#不就不卡了嘛

点评

编译会错误的魂淡,要加//  发表于 2011-7-18 20:43
这不是ruby.........  发表于 2011-7-18 18:31
误导帝自重  发表于 2011-7-18 18:30

评分

参与人数 1星屑 -4 收起 理由
精灵使者 -4 误导帝自重

查看全部评分

回复 支持 反对

使用道具 举报

Lv1.梦旅人

彩色的银子

梦石
0
星屑
50
在线时间
190 小时
注册时间
2006-6-13
帖子
1361

贵宾

3
发表于 2011-7-18 19:49:21 | 只看该作者
本帖最后由 神思 于 2011-7-18 20:02 编辑
  1. // TestC.cpp : 定义控制台应用程序的入口点。
  2. //

  3. #include "stdafx.h"

  4. #include <iostream>

  5. using namespace std;
  6. #include <stdio.h>
  7. #include <memory.h>

  8. typedef struct _tagSTACK_ITEM {
  9.         struct _tagSTACK_ITEM *next;
  10.         int value;
  11. } STACK_ITEM;

  12. typedef struct _tagSTACK {
  13.         int length;
  14.         STACK_ITEM *top;
  15. } STACK;

  16. short CreateStack(STACK* &ret_stack) {
  17.         STACK* stack = new STACK;
  18.         memset(stack, 0, sizeof(STACK));
  19.         stack->length = 0;
  20.         stack->top = 0;
  21.         ret_stack = stack;
  22.         return 1;
  23. }

  24. short CreateStackItem(int value, STACK_ITEM* ret_item) {
  25.         memset(ret_item, 0, sizeof(STACK_ITEM));
  26.         ret_item->value = value;
  27.         ret_item->next = 0;
  28.         return 1;
  29. }

  30. void StackPush(STACK *stack, int value) {
  31.         if (stack->top == 0) { /* if stack is empty, let the top of stack goto value. */
  32.                 STACK_ITEM* item = new STACK_ITEM;
  33.                 memset(item, 0, sizeof(STACK_ITEM));
  34.                 CreateStackItem(value, item);
  35.                 stack->top = item;
  36.         }
  37.         else { /* if not, insert a new node. */
  38.                 STACK_ITEM *item = new STACK_ITEM;
  39.                 CreateStackItem(value, item);
  40.                 item->next = stack->top;
  41.                 stack->top = item;
  42.         }
  43.         stack->length++;
  44. }

  45. int StackPop(STACK *stack, int *value) {
  46.         if (stack->length == 0) { /* if stack is null, then it will error. */
  47.                 *value = 0;
  48.                 return 0;
  49.         }
  50.         /* if not, pop a value. */
  51.         *value = stack->top->value;
  52.         /* move to next */
  53.          STACK_ITEM *stackItem = stack->top;
  54.         stack->top = stack->top->next;
  55.         stack->length--;
  56.         delete stackItem;
  57.         return 1;
  58. }

  59. int main() {


  60.         int i = 0;
  61.         int a = 0;
  62.         STACK * stack = 0;
  63.         CreateStack(stack);
  64.         StackPush(stack, 1);
  65.         StackPush(stack, 2);
  66.         StackPush(stack, 3);
  67.         StackPush(stack, 4);
  68.         StackPush(stack, 5);
  69.         for (i = 0; i < 5; i++) {
  70.                 if (StackPop(stack, &a)) {
  71.                         printf("%d\n", a);
  72.                 }
  73.                 else {
  74.                         printf("\aError! stack is empty! ");
  75.                         return -1;
  76.                 }
  77.         
  78.                 }
  79.                
  80.     return 0;
  81. }
复制代码
输出
5
4
3
2
1

点评

你敢告诉我你该什么了么  发表于 2011-7-18 20:03
-.-
回复 支持 反对

使用道具 举报

Lv2.观梦者

梦石
0
星屑
491
在线时间
339 小时
注册时间
2010-12-15
帖子
926

开拓者

4
 楼主| 发表于 2011-7-18 20:03:52 | 只看该作者
new STACK_ITEM……
大哥我这是C,不是C++……
回复 支持 反对

使用道具 举报

Lv1.梦旅人

彩色的银子

梦石
0
星屑
50
在线时间
190 小时
注册时间
2006-6-13
帖子
1361

贵宾

5
发表于 2011-7-18 20:07:29 | 只看该作者
本帖最后由 神思 于 2011-7-18 20:13 编辑

{:nm_7:}呃。。。那还不简单  改成malloc
  1. 你敢告诉我你该什么了么
复制代码
听这话,我怎么感觉我干了不该干的呢?

首先,这种先进后出叫做栈,不叫链表,
然后,
第一个错误点

short CreateStack(STACK * ret_stack) {
        STACK stack;
        memset(&stack, 0, sizeof(STACK));
        stack.length = 0;
        stack.top = 0;
        ret_stack = &stack;
        return 1;
}
这你带进来ret_stack只是一个引用地址,

然后
STACK_ITEM *item;
memset(item, 0, sizeof(STACK_ITEM));
有2处这里,根本未申请空间,你就给他来个归零.

然后,就是pop的时候你没delete
-.-
回复 支持 反对

使用道具 举报

Lv2.观梦者

梦石
0
星屑
491
在线时间
339 小时
注册时间
2010-12-15
帖子
926

开拓者

6
 楼主| 发表于 2011-7-18 20:20:01 | 只看该作者
本帖最后由 tamashii 于 2011-7-18 20:49 编辑

本来想说“写了个链栈”来着,怎么成链表了 - -bbbb
我还是好好学C语言吧
delete?那好像也是C++吧?
  1. #include <stdio.h>
  2. #include <memory.h>
  3. #include <malloc.h>

  4. typedef struct _tagSTACK_ITEM {
  5.         struct _tagSTACK_ITEM *next;
  6.         int value;
  7. } STACK_ITEM;

  8. typedef struct _tagSTACK {
  9.         int length;
  10.         STACK_ITEM *top;
  11. } STACK;

  12. short CreateStack(STACK *ret_stack) {
  13.         STACK *stack = malloc(sizeof(STACK));
  14.         memset(stack, 0, sizeof(STACK));
  15.         stack->length = 0;
  16.         stack->top = 0;
  17.         ret_stack = stack;
  18.         return 1;
  19. }

  20. short CreateStackItem(int value, STACK_ITEM *ret_item) {
  21.         STACK_ITEM *item = malloc(sizeof(STACK_ITEM));
  22.         memset(item, 0, sizeof(STACK_ITEM));
  23.         item->value = value;
  24.         item->next = 0;
  25.         ret_item = item;
  26.         return 1;
  27. }

  28. void StackPush(STACK *stack, int value) {
  29.         if (stack->top == 0) { /* if stack is empty, let the top of stack goto value. */
  30.                 STACK_ITEM *item = malloc(sizeof(STACK_ITEM));
  31.                 memset(item, 0, sizeof(STACK_ITEM));
  32.                 CreateStackItem(value, item);
  33.                 stack->top = item;
  34.         }
  35.         else { /* if not, insert a new node. */
  36.                 STACK_ITEM *item = malloc(sizeof(STACK_ITEM));
  37.                 CreateStackItem(value, item);
  38.                 item->next = stack->top;
  39.                 stack->top = item;
  40.         }
  41.         stack->length++;
  42. }

  43. int StackPop(STACK *stack, int *value) {
  44.         if (stack->length == 0) { /* if stack is null, then it will error. */
  45.                 *value = 0;
  46.                 return 0;
  47.         }
  48.         /* if not, pop a value. */
  49.         *value = stack->top->value;
  50.         /* move to next */
  51.         STACK_ITEM * temp = stack->top;
  52.         stack->top = stack->top->next;
  53.         stack->length--;
  54.         free(temp);
  55.         return 1;
  56. }

  57. int main() {
  58.         int i = 0;
  59.         int a = 0;
  60.         STACK * stack = 0;
  61.         CreateStack(stack);
  62.         StackPush(stack, 1);
  63.         StackPush(stack, 2);
  64.         StackPush(stack, 3);
  65.         StackPush(stack, 4);
  66.         StackPush(stack, 5);
  67.         for (i = 0; i < 5; i++) {
  68.                 if (StackPop(stack, &a)) {
  69.                         printf("%d\n", a);
  70.                 }
  71.                 else {
  72.                         printf("\aError! stack is empty! ");
  73.                         return -1;
  74.                 }
  75.         }
  76.         return 0;
  77. }
复制代码
修正了一下,但是还是无法运行 - -

点评

分段调试下?  发表于 2011-7-18 21:38
写C还不宏汇编= =  发表于 2011-7-18 21:38
delete貌似不是(大雾)  发表于 2011-7-18 20:44
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
8075
在线时间
7346 小时
注册时间
2010-7-16
帖子
4915

开拓者

7
发表于 2011-7-19 07:00:56 | 只看该作者
debug+watch应该就能找出错了吧。

现在的年轻人越来越强了。我身边那些靠编程拿工资的人写出来的东西都跟那啥一样,我认识的牛人都是把编程当成业余爱好的,这是什么道理呢?
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
110
在线时间
953 小时
注册时间
2007-4-25
帖子
805
8
发表于 2011-7-19 08:28:19 | 只看该作者
tamashii 发表于 2011-7-18 20:20
本来想说“写了个链栈”来着,怎么成链表了 - -bbbb
我还是好好学C语言吧
delete?那好像也是C++吧?修正了 ...

神思说的第一个错误你没有改。
  1. short CreateStack(STACK *ret_stack);
复制代码
这里的 ret_stack 是单间接引用,它仅仅是调用者传递的指针的一个拷贝,指向与调用者指针相同的地址。因此,你在 CreateStack 中修改 ret_stack,修改的仅仅是在 CreateStack 函数中的局部变量 `ret_stack',而无法修改调用者非局部的指针。为了修改调用者的指针,调用者必须能够传递指针本身的地址,所以这里可以使用双间接引用,然后修改时通过 * 运算符反引用一下 ret_stack 即可。
  1. short CreateStack(STACK **ret_stack) {
  2.         ...
  3.         *ret_stack = stack;
  4.         ...
  5. }
复制代码
调用的时候,就要传递指针的地址,而不是指针指向的地址,如下:
  1.         STACK * stack = 0;
  2.         CreateStack(&stack);
复制代码
CreateStackItem 也是一个道理。像这种分配一个结构实例的场合,我通常会直接返回实例的地址,但有时可能需要返回函数错误代码,所以需要双间接引用。

别的一些问题:

1、分配初始为 0 的内存不需要额外去调用一次 memset,直接用 calloc 即可。

2、57 行的 STACK_ITEM * temp = stack->top; 这一句与 C89 是不兼容的,只有 C99 才兼容。C89 要求所有的变量声明都处于代码块顶部而不能出现在非声明语句之后。
[email protected]:~> repeat 1 fortune
Matz is nice, so we are nice.
回复 支持 反对

使用道具 举报

Lv1.梦旅人

风之塞尔达

梦石
0
星屑
50
在线时间
57 小时
注册时间
2005-10-22
帖子
2492

贵宾

9
发表于 2011-7-19 14:35:27 | 只看该作者
本帖最后由 link006007 于 2011-7-19 14:46 编辑

弄清变量作用域是什么就没问题了。。
还要注意 pop出的栈元素的回收
C遵循谁申请谁释放

做IT技术,编程不可能成为业余爱好  即使你是CTO,架构师,分析师
只是很多非核心代码你是交给别人去写,但是你要保证整个工程每个人代码的质量
把写程序当成业余爱好的CTO无法做到保证整体上的工程代码质量
在程序里延续塞尔达的传说, 在画板上勾勒塞尔达的轮廓!!
回复 支持 反对

使用道具 举报

Lv1.梦旅人

彩色的银子

梦石
0
星屑
50
在线时间
190 小时
注册时间
2006-6-13
帖子
1361

贵宾

10
发表于 2011-7-19 14:39:11 | 只看该作者
我是来吐槽的
// TestC.cpp : 定义控制台应用程序的入口点。
大哥我这是C,不是C++……
-.-
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-16 13:57

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表