我编写了一个程序,将Infix表达式转换为Postfix表达式。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Stack{
int top;
int capacity;
char *array;
}Stack;
int isEmpty(Stack *s){
return s->top == -1;
}
char pop(Stack *s){
char c;
if(isEmpty(s))
return -1;
c = s->array[s->top];
s->array[s->top--] = '\0';
return c;
}
void push(Stack *s,char c){
s->array[++s->top] = c;
}
char peek(Stack *s){
return s->array[s->top];
}
char *toString(char c){
char *str = (char *)malloc(sizeof(char)*2);
str[0] = c;
str[1] = '\0';
return str;
}
int hasGreaterPriority(char c1,char c2){
if(c1 == '*' && (c2 == '+' || c2 == '-'))
return 1;
else if(c1 == '/' && (c2 == '+' || c2 == '-'))
return 1;
else
return 0;
}
void infixtopostfix(char exp[]){
int len = strlen(exp),i;
char *out = (char *)malloc(sizeof(char));
out[0] = '\0';
Stack *stack = (Stack *)malloc(sizeof(Stack));
stack->capacity = len;
stack->top = -1;
stack->array = malloc(sizeof(char)*len);
for(i=0; i<len; i++){
if(exp[i] >= 'a' && exp[i] <= 'z')
strcat(out,toString(exp[i]));
else if(exp[i] == ')'){
while(peek(stack) != '(')
strcat(out,toString(pop(stack)));
pop(stack);
}
else{
if(isEmpty(stack) || exp[i] == '(')
push(stack,exp[i]);
else if(hasGreaterPriority(peek(stack),exp[i])){
strcat(out,toString(pop(stack)));
push(stack,exp[i]);
}
else
push(stack,exp[i]);
}
}
/* UNTIL HERE */
while(!isEmpty(stack))
strcat(out,toString(pop(stack)));
printf("Postfix Expression: %s\n",out);
}
int main(void) {
char exp[] = "a+b*(c/d-e)/(f+g*h)-i\0";
printf("Infix Expression: %s\n",exp);
infixtopostfix(exp);
return 0;
}
问题如下:
在infixtopostfix方法中,之前由&#34; UNTIL HERE&#34;表示。变量值似乎是正确的。我在gdb的帮助下检查过。在while循环的2次迭代之后,out变量中的值似乎也没问题。在最后一次迭代中,即在将+加入out时,该值变为如下
abcd/e-fgh*+/i-*\377\377\377\377\025+
\377\377\377\377\025+
如何被添加到变量中?
预期值为abcd/e-fgh*+/i-*+
答案 0 :(得分:4)
您已为空字符串分配空间:
char *out = (char *)malloc(sizeof(char));
out[0] = '\0';
然后你做:
strcat(out,toString(exp[i]));
没有足够的空间分配给out
的末尾添加任何内容。可能会在某处重新分配,但它隐藏得很好。
从文体上讲,你有:
if(exp[i] >= 'a' && exp[i] <= 'z')
strcat(out,toString(exp[i]));
else if(exp[i] == ')'){
while(peek(stack) != '(')
strcat(out,toString(pop(stack)));
pop(stack);
}
else{
if(isEmpty(stack) || exp[i] == '(')
push(stack,exp[i]);
else if(hasGreaterPriority(peek(stack),exp[i])){
strcat(out,toString(pop(stack)));
push(stack,exp[i]);
}
else
push(stack,exp[i]);
}
您可以通过以下方式避免嵌套级别:
if(exp[i] >= 'a' && exp[i] <= 'z')
strcat(out,toString(exp[i]));
else if(exp[i] == ')'){
while(peek(stack) != '(')
strcat(out,toString(pop(stack)));
pop(stack);
}
else if(isEmpty(stack) || exp[i] == '(')
push(stack,exp[i]);
else if(hasGreaterPriority(peek(stack),exp[i])){
strcat(out,toString(pop(stack)));
push(stack,exp[i]);
}
else
push(stack,exp[i]);
这是自洽的;原件不是。
我接受了你的代码,在除static
之外的每个函数之前添加了main()
(主要是为了绕过我的默认编译选项),然后在valgrind
下运行你的代码来获取输出:
$ valgrind ./pfx-infix
==17722== Memcheck, a memory error detector
==17722== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==17722== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==17722== Command: ./pfx-infix
==17722==
Infix Expression: a+b*(c/d-e)/(f+g*h)-i
==17722== Invalid write of size 1
==17722== at 0x4C2BEF3: strcat (mc_replace_strmem.c:268)
==17722== by 0x4005D4: main (pfx-infix.c:67)
==17722== Address 0x51f2041 is 0 bytes after a block of size 1 alloc'd
==17722== at 0x4C2935F: malloc (vg_replace_malloc.c:291)
==17722== by 0x4004FF: main (pfx-infix.c:57)
==17722==
==17722== Invalid read of size 1
==17722== at 0x4C2BEC4: strcat (mc_replace_strmem.c:268)
==17722== by 0x4005D4: main (pfx-infix.c:67)
==17722== Address 0x51f2041 is 0 bytes after a block of size 1 alloc'd
==17722== at 0x4C2935F: malloc (vg_replace_malloc.c:291)
==17722== by 0x4004FF: main (pfx-infix.c:57)
==17722==
==17722== Invalid write of size 1
==17722== at 0x4C2BEE0: strcat (mc_replace_strmem.c:268)
==17722== by 0x4005D4: main (pfx-infix.c:67)
==17722== Address 0x51f2041 is 0 bytes after a block of size 1 alloc'd
==17722== at 0x4C2935F: malloc (vg_replace_malloc.c:291)
==17722== by 0x4004FF: main (pfx-infix.c:57)
==17722==
==17722== Invalid read of size 1
==17722== at 0x4C2BEC4: strcat (mc_replace_strmem.c:268)
==17722== by 0x400726: main (pfx-infix.c:77)
==17722== Address 0x51f2041 is 0 bytes after a block of size 1 alloc'd
==17722== at 0x4C2935F: malloc (vg_replace_malloc.c:291)
==17722== by 0x4004FF: main (pfx-infix.c:57)
==17722==
==17722== Invalid write of size 1
==17722== at 0x4C2BEE0: strcat (mc_replace_strmem.c:268)
==17722== by 0x400726: main (pfx-infix.c:77)
==17722== Address 0x51f2044 is 3 bytes after a block of size 1 alloc'd
==17722== at 0x4C2935F: malloc (vg_replace_malloc.c:291)
==17722== by 0x4004FF: main (pfx-infix.c:57)
==17722==
==17722== Invalid write of size 1
==17722== at 0x4C2BEF3: strcat (mc_replace_strmem.c:268)
==17722== by 0x400726: main (pfx-infix.c:77)
==17722== Address 0x51f2045 is 4 bytes after a block of size 1 alloc'd
==17722== at 0x4C2935F: malloc (vg_replace_malloc.c:291)
==17722== by 0x4004FF: main (pfx-infix.c:57)
==17722==
==17722== Invalid read of size 1
==17722== at 0x4C2BEC4: strcat (mc_replace_strmem.c:268)
==17722== by 0x4006A9: main (pfx-infix.c:70)
==17722== Address 0x51f2041 is 0 bytes after a block of size 1 alloc'd
==17722== at 0x4C2935F: malloc (vg_replace_malloc.c:291)
==17722== by 0x4004FF: main (pfx-infix.c:57)
==17722==
==17722== Invalid write of size 1
==17722== at 0x4C2BEE0: strcat (mc_replace_strmem.c:268)
==17722== by 0x4006A9: main (pfx-infix.c:70)
==17722== Address 0x51f2046 is 5 bytes after a block of size 1 alloc'd
==17722== at 0x4C2935F: malloc (vg_replace_malloc.c:291)
==17722== by 0x4004FF: main (pfx-infix.c:57)
==17722==
==17722== Invalid write of size 1
==17722== at 0x4C2BEF3: strcat (mc_replace_strmem.c:268)
==17722== by 0x4006A9: main (pfx-infix.c:70)
==17722== Address 0x51f2047 is 6 bytes after a block of size 1 alloc'd
==17722== at 0x4C2935F: malloc (vg_replace_malloc.c:291)
==17722== by 0x4004FF: main (pfx-infix.c:57)
==17722==
==17722== Invalid read of size 1
==17722== at 0x4C2BEC4: strcat (mc_replace_strmem.c:268)
==17722== by 0x40061E: main (pfx-infix.c:86)
==17722== Address 0x51f2041 is 0 bytes after a block of size 1 alloc'd
==17722== at 0x4C2935F: malloc (vg_replace_malloc.c:291)
==17722== by 0x4004FF: main (pfx-infix.c:57)
==17722==
==17722== Invalid write of size 1
==17722== at 0x4C2BEE0: strcat (mc_replace_strmem.c:268)
==17722== by 0x40061E: main (pfx-infix.c:86)
==17722== Address 0x51f204e is 13 bytes after a block of size 1 alloc'd
==17722== at 0x4C2935F: malloc (vg_replace_malloc.c:291)
==17722== by 0x4004FF: main (pfx-infix.c:57)
==17722==
==17722== Invalid write of size 1
==17722== at 0x4C2BEF3: strcat (mc_replace_strmem.c:268)
==17722== by 0x40061E: main (pfx-infix.c:86)
==17722== Address 0x51f204f is 14 bytes after a block of size 1 alloc'd
==17722== at 0x4C2935F: malloc (vg_replace_malloc.c:291)
==17722== by 0x4004FF: main (pfx-infix.c:57)
==17722==
==17722== Invalid read of size 1
==17722== at 0x4E7D3B1: vfprintf (vfprintf.c:1630)
==17722== by 0x4E858D8: printf (printf.c:35)
==17722== by 0x400633: main (pfx-infix.c:88)
==17722== Address 0x51f2041 is 0 bytes after a block of size 1 alloc'd
==17722== at 0x4C2935F: malloc (vg_replace_malloc.c:291)
==17722== by 0x4004FF: main (pfx-infix.c:57)
==17722==
==17722== Invalid read of size 1
==17722== at 0x4EAC184: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1330)
==17722== by 0x4E7CF81: vfprintf (vfprintf.c:1630)
==17722== by 0x4E858D8: printf (printf.c:35)
==17722== by 0x400633: main (pfx-infix.c:88)
==17722== Address 0x51f2050 is 15 bytes after a block of size 1 alloc'd
==17722== at 0x4C2935F: malloc (vg_replace_malloc.c:291)
==17722== by 0x4004FF: main (pfx-infix.c:57)
==17722==
==17722== Invalid read of size 1
==17722== at 0x4EAC199: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1330)
==17722== by 0x4E7CF81: vfprintf (vfprintf.c:1630)
==17722== by 0x4E858D8: printf (printf.c:35)
==17722== by 0x400633: main (pfx-infix.c:88)
==17722== Address 0x51f204f is 14 bytes after a block of size 1 alloc'd
==17722== at 0x4C2935F: malloc (vg_replace_malloc.c:291)
==17722== by 0x4004FF: main (pfx-infix.c:57)
==17722==
==17722== Invalid read of size 16
==17722== at 0x4EAC0DE: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1362)
==17722== by 0x4E7CF81: vfprintf (vfprintf.c:1630)
==17722== by 0x4E858D8: printf (printf.c:35)
==17722== by 0x400633: main (pfx-infix.c:88)
==17722== Address 0x51f2040 is 0 bytes inside a block of size 1 alloc'd
==17722== at 0x4C2935F: malloc (vg_replace_malloc.c:291)
==17722== by 0x4004FF: main (pfx-infix.c:57)
==17722==
==17722== Invalid read of size 1
==17722== at 0x4EAC100: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1362)
==17722== by 0x4E7CF81: vfprintf (vfprintf.c:1630)
==17722== by 0x4E858D8: printf (printf.c:35)
==17722== by 0x400633: main (pfx-infix.c:88)
==17722== Address 0x51f2050 is 15 bytes after a block of size 1 alloc'd
==17722== at 0x4C2935F: malloc (vg_replace_malloc.c:291)
==17722== by 0x4004FF: main (pfx-infix.c:57)
==17722==
Postfix Expression: abcd/e-fgh*+/i-*+
==17722==
==17722== HEAP SUMMARY:
==17722== in use at exit: 72 bytes in 20 blocks
==17722== total heap usage: 20 allocs, 0 frees, 72 bytes allocated
==17722==
==17722== LEAK SUMMARY:
==17722== definitely lost: 51 bytes in 19 blocks
==17722== indirectly lost: 21 bytes in 1 blocks
==17722== possibly lost: 0 bytes in 0 blocks
==17722== still reachable: 0 bytes in 0 blocks
==17722== suppressed: 0 bytes in 0 blocks
==17722== Rerun with --leak-check=full to see details of leaked memory
==17722==
==17722== For counts of detected and suppressed errors, rerun with: -v
==17722== ERROR SUMMARY: 204 errors from 17 contexts (suppressed: 2 from 2)
$
这清楚地标识了超出范围的存储器访问;它也恰好产生了正确的&#39;回答。您还有许多应该修复的内存泄漏。
答案 1 :(得分:2)
stack->array = malloc(sizeof(sizeof(char)*len));
必须:
stack->array = malloc(len);
sizeof(sizeof(char)*len))
= sizeof(size_t)
(sizeof
运营商返回的类型)
答案 2 :(得分:-1)
如果您想找到将中缀转换为后缀和前缀的确切答案,请访问此处。在这里,我没有使用指针编程。因此,在开始For infix expression to prefix and postfix
时很容易理解