이전에 몇 가지 질문을했지만 문제의 근본 원인을 찾은 것 같습니다. , 방법은 다음 FREELIST의 목록을 무료로 사용할 수있는 새로운 문자열을 요청하도록되어 한 번 루프를 통해 실행 한 후C : 내가 원하는 것 이상 자유롭게 해 주시겠습니까?
for (;;) {
printf ("(%d)$ ", ncmd); // Prompt for command
if ((line = getLine(stdin)) == NULL) // Read line
break; // Break on end of file
cmd = hExpand (line, &status); // Expand line
free (line);
if (status > 0) // Substitution?
fputs (cmd, stdout); // Print expanded line
else if (status < 0)
fputs ("substitution failed\n", stderr);
list = lex (cmd); // Lex line into tokens
free (cmd);
if (list == NULL) // Empty token list?
continue;
hRemember (ncmd, list); // Remember command
if (status >= 0) // No substitution error?
process (list); // Process token list
freeList (list); // Free token list
ncmd++; // Adjust prompt
}
:
나는이 루프를 포함하는 프로그램 mainLex.c이 명부. 이것은 모두 좋고 좋지만, 나는 freeList가 내가 그것을 요구하지 않는 것들을 자유롭게하고 있음을 발견하고있다! 특히, 그것은 글로벌 정적 데이터 구조 llist를 해제하고 있으며, 이것이 어떻게 일어나고 있는지 잘 모르겠습니다.
FREELIST의 코드 :
는void freeList (token *list)
{
token *p, *pnext;
for (p = list; p; p = pnext) {
pnext = p->next;
free(p->text);
free(p); //This is apparently where the data structure is being freed
}
}
hRemember :
이void hRemember (int ncmd, token *list)
{
command* curr;
curr = (struct command *)malloc(sizeof(struct command));
token *list1 = malloc(sizeof(token));
list1=list;
f = ncmd;
curr->cmmd=(struct token *)malloc(sizeof(struct token));
curr->cmmd=list1;
curr->num=ncmd;
curr->prev=llist;
if (llist==NULL)
{
llist = (struct command *)malloc(sizeof(struct command));
}
llist->nextcmd=curr;
llist=curr;
}
llist가 :
typedef struct command { // Struct for each token in linked list
token *cmmd; // String containing token
int num; // Corresponding type
struct command *prev;
struct command *nextcmd; // Pointer to next token in linked list
} command;
command* llist = NULL; //This is global in a different c file than the loop
내가 루프의 한 버전 이후 llist의 내용을 읽으려고하면, 이것이 무슨 일이 올지 :
==12878== Invalid read of size 8
==12878== at 0x400DB5: hDump (Lex1.c:153)
==12878== by 0x400BA9: process (mainLex.c:66)
==12878== by 0x400B0C: main (mainLex.c:41)
==12878== Address 0x51f34f0 is 0 bytes inside a block of size 24 free'd
==12878== at 0x4C29577: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==12878== by 0x400C0E: freeList (mainLex.c:81)
==12878== by 0x400B18: main (mainLex.c:43)
==12878==
==12878== Invalid read of size 1
가능한 경우 루프 또는 freeList를 변경하지 않습니다.
편집 : 렉스 루틴, llist를 사용한다 (나는 많은이를 정리해야하지만, 현재로서는 기능입니다) hRemember에서
token *lex (const char *line)
{
if (strcspn(line, METACHARS)==strlen(line))
{
token *head, *temp, *right, *temp1;
char *line1 = strdup(line);
char *curr = separate(line1);
temp = (token *)malloc(sizeof(token));
temp->text=strdup(curr);
temp->type=10;
head=temp;
head->next=NULL;
curr=separate(NULL);
while (curr!=NULL)
{
temp1 = (token *)malloc(sizeof(token));
right = head;
while (right->next != NULL)
{
right=right->next;
}
temp1->text=strdup(curr);
temp1->type=10;
temp1->next=NULL;
right->next=temp1;
curr=separate(NULL);
}
return head;
}
else
{
token *head, *temp, *right, *temp1;
char *line1 = strdup(line);
char *curr = separate(line1);
temp = (token *)malloc(sizeof(token));
temp->text=strdup(curr);
if (strcmp(temp->text,"<")==0)
{
temp->type=20;
}
else if (strcmp(temp->text,"<<")==0)
{
temp->type=21;
}
else if (strcmp(temp->text,"|")==0)
{
temp->type=30;
}
else if (strcmp(temp->text,">")==0)
{
temp->type=31;
}
else if (strcmp(temp->text,">>")==0)
{
temp->type=32;
}
else if (strcmp(temp->text,";")==0)
{
temp->type=40;
}
else if (strcmp(temp->text,"&")==0)
{
temp->type=41;
}
else if (strcmp(temp->text,"&&")==0)
{
temp->type=42;
}
else if (strcmp(temp->text,"||")==0)
{
temp->type=43;
}
else if (strcmp(temp->text,"(")==0)
{
temp->type=50;
}
else if (strcmp(temp->text,")")==0)
{
temp->type=51;
}
else
{
temp->type=10;
}
head=temp;
head->next=NULL;
curr=separate(NULL);
while (curr!=NULL)
{
temp1 = (token *)malloc(sizeof(token));
right = head;
while (right->next != NULL)
{
right=right->next;
}
temp1->text=strdup(curr);
if (strcmp(temp1->text,"<")==0)
{
temp1->type=20;
}
else if (strcmp(temp1->text,"<<")==0)
{
temp1->type=21;
}
else if (strcmp(temp1->text,"|")==0)
{
temp1->type=30;
}
else if (strcmp(temp1->text,">")==0)
{
temp1->type=31;
}
else if (strcmp(temp1->text,">>")==0)
{
temp1->type=32;
}
else if (strcmp(temp1->text,";")==0)
{
temp1->type=40;
}
else if (strcmp(temp1->text,"&")==0)
{
temp1->type=41;
}
else if (strcmp(temp1->text,"&&")==0)
{
temp1->type=42;
}
else if (strcmp(temp1->text,"||")==0)
{
temp1->type=43;
}
else if (strcmp(temp1->text,"(")==0)
{
temp1->type=50;
}
else if (strcmp(temp1->text,")")==0)
{
temp1->type=51;
}
else
{
temp1->type=10;
}
temp1->next=NULL;
right->next=temp1;
curr=separate(NULL);
}
return head;
}
}
내가 당신의'list' 객체의 이름을 바꾸는 생각 하는데요 'my_list'일지라도. 내 머리 속의 파서는'std :: list'와 혼동을 계속합니다. 어쩌면'token_list'는 좋은 이름일까요? – Baldrickk