#define MAXL 256
第一遍:in = "25 7 * 14 - 6 +";
运行顺利,答案正确。
第二次传递:in = "1 24 3 + * 41 -";
程序在输出Num got in: 41
后立即停止预期:继续循环然后进入减号然后pop(s)
并减去41
我猜测我的程序耗尽了分配的空间,因为free()
没有像我预期的那样完成他们的工作,但我不确定。
非常感谢任何帮助。谢谢!
double evaluatePost(char * in)
{
double * op1 = NULL, * op2 = NULL, * msgr = NULL;
int i, j;
char * c = {0}, tempExp[MAXL] = {0};
char ** token = NULL;
Stack * s = createStack();
strcpy(tempExp, in); /* Copy in to a temporary array so strtok will not destroy in */
for(c = strtok(tempExp, " "); c != NULL; ++i, c = strtok(NULL, " "))
{
if(isdigit(c[0]))
{
printf("\nNum got in: %s\n", c); /* Crash right after this line output 41 */
system("PAUSE");
msgr = (double*)malloc(sizeof(double)); /* I made a malloc check here, it never showed error */
*msgr = atoi(c); /* I don't know if it crash at this line or the next one */
push(s, msgr); /* stack has no limit, receives stack* and void* */
/* It never got pass to here after output 41 */
}
else
{
op2 = (double *)pop(s);
op1 = (double *)pop(s);
printf("\n%f %f %s\n", *op1, *op2, c);
system("PAUSE");
msgr = (double*)malloc(sizeof(double));
if(!msgr)
{
printf("Memory allocation failed.\n");
system("PAUSE");
exit(1);
}
switch(*c)
{
case '+': *msgr = (*op1 + *op2); break;
case '-': *msgr = (*op1 - *op2); break;
case '*': *msgr = (*op1 * *op2); break;
case '/': *msgr = (*op1 / *op2); break;
}
printf("\n%.1f\n", *msgr);
system("PAUSE");
/* Free the memory before they become orphans */
free(op1), free(op2);
push(s, msgr);
}
}
returnVal = *((double *)pop(s));
makeEmpty(s);
return returnVal;
}
void push(Stack * stack, void * dataInPtr)
{
/* Define a new StackNode */
StackNode * newPtr;
/* Get some Memory */
newPtr = (StackNode*)malloc(sizeof(StackNode));
if(!newPtr)
{
printf("Out of memory");
system("PAUSE");
exit(1);
}
/* Assign dataIn to dataPtr */
newPtr->dataPtr = dataInPtr;
/* Make the links */
newPtr->link = stack->top; /* Point both to top */
stack->top = newPtr; /* newPtr at top pointed to be head */
(stack->count)++;
}
void * pop(Stack * stack)
{
/* Hold the data */
void * dataOutPtr;
StackNode * temp;
/* Check if stack is empty */
if(stack->count == 0)
dataOutPtr = NULL;
else
{
/* Get the data and remove the node */
temp = stack->top; /* temp points to top */
dataOutPtr = stack->top->dataPtr; /* dataOutPtr has data */
stack->top = stack->top->link; /* stack moves to next node */
temp->link = NULL; /* break top node off stack */
free(temp); /* frees memory */
(stack->count)--;
}
return dataOutPtr;
}
typedef struct node
{
void * dataPtr;
struct Node * link;
} StackNode;
typedef struct
{
int count;
StackNode * top;
} Stack;
答案 0 :(得分:0)
你的问题可能在于:
您正在释放pop()
temp = stack->top; /* temp points to top */
dataOutPtr = stack->top->dataPtr; /* dataOutPtr has data */
stack->top = stack->top->link; /* stack moves to next node */
temp->link = NULL; /* break top node off stack */
free(temp); /* frees memory */
之后,您将evaluatePost()
中的节点中的数据指针释放:
free(op1), free(op2);
内存的free
序列应始终与malloc
的顺序相反,即您应先分配Node,然后分配节点数据,并free
free
节点首先是数据,然后是Node
本身。
您在使用某些输入时遇到问题而没有其他输入,因为这是未定义的行为。
要了解有关C中未定义行为的更多信息,您可以在SO中搜索相关问题。
答案 1 :(得分:0)
您可以轻松添加遍历堆栈中所有节点的功能,而无需释放它们。如果您需要使用集合pushing
所有节点并且不希望pop
和free
数据,或者您需要更新节点,这会派上用场以popping
之前的某种方式。您需要做的就是向堆栈添加一个tail
指针,该指针将第一个节点pushed
的地址保存到堆栈中。 e.g:
typedef struct
{
int count;
StackNode *top;
StackNode *tail;
} Stack;
为什么呢?由于您有StackNode->link
,因此无论如何,您的数据实际上都是linked-list
形式。将指向第一个节点tail
的{{1}}指针添加到堆栈中,只需简单地了解何时停止迭代pushed
。通过一些小的调整,您可以执行您尝试的操作 - 迭代堆栈中的所有节点,而无需执行nodes
/ pop
节点。
这是一个简短的例子,显示了所需的小调整。另请注意,清除会删除free
的所有强制转换(不要这样做),并在malloc
调用自己的几次清理:
malloc
示例/输出强>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node
{
void *dataPtr;
struct node *link;
} StackNode;
typedef struct
{
int count;
StackNode *top;
StackNode *tail;
} Stack;
Stack *stackcreate ()
{
Stack *s = malloc (sizeof *s);
if (!s) {
fprintf (stderr, "%s() error: memory allocation failed.\n", __func__);
exit (EXIT_FAILURE);
}
s->count = 0;
s->top = s->tail = NULL;
return s;
}
void push(Stack * stack, void * dataInPtr)
{
if (!stack) return;
/* Define a new StackNode & allocate */
StackNode *newPtr = malloc (sizeof *newPtr);
if(!newPtr)
{
fprintf (stderr, "%s() error: memory allocation failed.\n", __func__);
exit (EXIT_FAILURE);
}
/* Assign dataIn to dataPtr */
newPtr->dataPtr = dataInPtr;
newPtr->link = stack->top; /* Point both to top */
/* Make the links */
if (!stack->top)
stack->tail = newPtr;
stack->top = newPtr; /* newPtr at top pointed to be head */
(stack->count)++;
}
void * pop(Stack * stack)
{
/* Hold the data */
void * dataOutPtr;
StackNode * temp;
/* Check if stack is empty */
if(stack->count == 0)
dataOutPtr = NULL;
else
{
/* Get the data and remove the node */
temp = stack->top; /* temp points to top */
dataOutPtr = stack->top->dataPtr; /* dataOutPtr has data */
stack->top = stack->top->link; /* stack moves to next node */
temp->link = NULL; /* break top node off stack */
free(temp); /* frees memory */
(stack->count)--;
if (!stack->top) stack->tail = NULL;
}
return dataOutPtr;
}
int main (void) {
char *lines[] = { "my cat has more...",
"has lots of fleas, ",
"my dog, the lab, " };
size_t i = 0;
size_t entries = sizeof lines/sizeof *lines;
Stack *stack = stackcreate ();
for (i = 0; i < entries; i++)
push (stack, (void *)lines[i]);
printf (" \niterating over nodes in stack without popping\n\n");
StackNode *p;
for (p = stack->top; ;p = p->link) {
printf (" %s\n", (char *)p->dataPtr);
if (p == stack->tail)
break;
}
printf ("\n popping items from stack\n\n");
while (stack->top) {
printf (" %s\n", (char *)pop (stack));
}
printf ("\n");
return 0;
}