나는 들소를 배우고 문제를 만난다. {1, 2, 3}과 같은 정수 세트를 허용하도록 RE를 설계하려고합니다. 다음은 제 코드의 일부입니다. 간단한 계산이 세트 코드가 올바르게 작동 - I 입력 "{2} {1}"때들소에서 메모리를 어떻게 관리합니까?
printf("given {, str_to_out before %s \n", str_to_out);
str_to_out[0] = '{';
printf("given {, str_to_out after %s \n", str_to_out);
문제이다. 다음과 같이 두 장이 찍혔습니다.
given {, str_to_out before
given {, str_to_out after {1}
무엇이 문제입니까? 메모리 관리에 문제가있어 이해할 수 없기 때문에 생각합니다. 도와 주신 모든 분들께 감사드립니다 !! 다른 코드는 다음과 같습니다. "MinusPoly ($$, $ 1, $ 3)"함수에서 시작하여 "Format()"-> "Expand()"순서로 프로세스가 시작됩니다. 문제는에 일어나는 "확장()"
%{
#define YYSTYPE char *
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXL 5000
int yyerror(const char* s);
int yylex(void);
void MinusPoly(char *a,const char *p1, const char *p2);
void Format(char* str);
void AppendIntToStr(char* str, int num);
void Expand(char* str);
void RmRedunInt(char *str_to_out);
void StrToIntList(char *str, int list[], int *count);
int IsExist(int target, int list[], int length);
void IntListToStr(char *str, int list[], int length);
void RmWs(char* str);
%}
%token NUM
%token LB RB POLY BRACE SET INTERSECT UNION MAX MIN
%left '-' '+'
%left '*' '/' DOTM
%right '^'
%%
/* grammar rules and actions follow in {}*/
input: input line
| line
;
line: '\n'
| expr '\n' {printf("res %s\n",$1);}
;
expr: expr '-' expr_md {MinusPoly($$,$1,$3);}
| expr '+' expr_md {}
| expr_md {$$=$1;}
;
expr_md: expr_md '*' expr_hi {printf("multiply \n");}
| expr_md '/' expr_hi {}
| expr_hi {$$=$1;}
;
expr_hi: LB expr RB {$$ = $2;}
| SET {printf("set %s\n",$1);}
;
%%
#include<ctype.h>
int main(void){
return yyparse();
}
int yyerror(const char* s) { return 0; }
void MinusPoly(char *a,const char *p1, const char *p2){
int l1 = strlen(p1), l2 = strlen(p2);
int i;
char s, np1[MAXL],np2[MAXL];
strcpy(np1,p1);
strcpy(np2,p2);
Format(np1);
Format(np2);
printf("np1 %s\n",np1);
printf("np2 %s\n",np2);
return;
}
void Format(char* str){
char temp[MAXL];
int i, j ,len;
strcpy(temp,str);
RmWs(temp);
Expand(temp);
len = strlen(temp);
printf("str is %s\n",temp);
for(i=0; i < len; i ++){
str[i] = temp[i];
}
str[i] = '\0';
return;
}
void Expand(char* str){
int i,j, len, outlen = 0, num1, num2,len1 = 0, len2 = 0,curr_num = 0;
char temp_sbl;
char str_to_out[MAXL], str_range[10], str_num[10];
strcpy(str_to_out,"");
len = strlen(str);
printf("input str is %s, length %d\n",str,len);
if(len <= 2)
return;
for(i = 0 ;i < len; i ++){
temp_sbl = str[i];
if(temp_sbl == '{'){
printf("given {, str_to_out before %s \n", str_to_out);
str_to_out[0] = '{';
printf("given {, str_to_out after %s \n", str_to_out);
outlen++;
continue;
}
if(temp_sbl == '-'){
num1 = curr_num;
num2 = 0;
curr_num = 0;
for(j = i + 1; j <len; j ++){
if(!isdigit(str[j])){
break;
}
num2 = num2 * 10 + str[j] - '0';
}
i = j;
if(num1 <= num2){
for(j = num1; j <=num2; j++){
AppendIntToStr(str_to_out,j);
outlen = strlen(str_to_out);
if(j<num2){
str_to_out[outlen] = ',';
outlen++;
}
}
}
else{
for(j = num2; j <=num1; j++){
AppendIntToStr(str_to_out,j);
outlen = strlen(str_to_out);
if(j<num1){
str_to_out[outlen] = ',';
outlen++;
}
}
}
str_to_out[outlen] = str[i];
outlen++;
continue;
}
if(temp_sbl == ',' || temp_sbl == '}'){
AppendIntToStr(str_to_out,curr_num);
outlen = strlen(str_to_out);
str_to_out[outlen] = temp_sbl;
outlen++;
curr_num = 0;
continue;
}
curr_num = curr_num * 10 + str[i] - '0';
}
strcpy(str,"");
RmRedunInt(str_to_out);
strcpy(str,str_to_out);
return;
}
void IntListToStr(char *str, int list[], int length){
int i,j, len = 0;
char str_num[50];
str[0] = '{';
len = 1;
for(i = 0 ; i < length; i ++){
strcpy(str_num,"");
sprintf(str_num,"%d",list[i]);
strcat(str,str_num);
len = strlen(str);
if(i < length - 1)
str[len] = ',';
else
str[len] = '}';
len++;
}
return;
}
int IsExist(int target, int list[], int length){
if(length==0)
return 0;
int i;
for(i=0;i<length;i++)
if(list[i]==target)
return i+1;
return 0;
}
void StrToIntList(char *str, int list[], int *count){
int i, j , tempcount = 0, temp_ls[1000], len = strlen(str);
int curr_num = 0;
for(i = 0 ; i < len ; i ++){
if(str[i] == '{')
continue;
if(str[i] == ',' || str[i] == '}'){
list[tempcount] = curr_num;
tempcount++;
curr_num = 0;
continue;
}
curr_num = curr_num * 10 + str[i] - '0';
}
*count = tempcount;
return;
}
void RmRedunInt(char *str_to_out){
int i,j ,len;
int ls_num[1000],count = 0, temp_ls[1000], tempcount = 0;
char str_temp[MAXL];
strcpy(str_temp,"");
StrToIntList(str_to_out,temp_ls,&tempcount);
for(i = 0; i < tempcount; i ++){
if(IsExist(temp_ls[i],ls_num,count))
continue;
ls_num[count] = temp_ls[i];
count++;
}
IntListToStr(str_temp,ls_num,count);
strcpy(str_to_out,"");
strcpy(str_to_out,str_temp);
return;
}
void AppendIntToStr(char* str, int num){
char str_num[50];
strcpy(str_num,"");
sprintf(str_num,"%d",num);
strcat(str,str_num);
return;
}
감사합니다. 필자가 다른 작은 프로그램을 시작하고 들소를 사용하지 않고이 모든 기능을 넣으므로 아마도 아마도 들소의 문제가 아닐 것입니다. 문제도 발생합니다. "str_to_out"문자열이 "Expand()"함수가 종료 될 때 해제되지 않는 것 같습니다. 무엇이 문제입니까 ... – pfc
자동 변수이기 때문에 해제됩니다. 그러나 나는'str_to_out'을'\ 0'으로 끝내지 않는다는 것을 알 수 있습니다. 예를 들어 그렇게해야합니다. AppendIntToStr를 호출하기 전에. 자동 변수는 0으로 초기화되지 않습니다. 또한 디버거를 사용하여 진행 상황을 확인하는 것이 좋습니다. –
질문이 하나 더 있습니다. $$을 매개 변수로 전달하기 때문에 MinusPoly에 대한 내 호출은 문자열이라고했습니다. 그 이유는이 "$$ = MinusPoly ($ 1, $ 3)"을 시도했지만, 돌아 왔을 때 로컬 포인터를 반환 할 수 없다고보고합니다. 그것을 고칠 방법이 있습니까? 고맙습니다! – pfc