以前我已经问过几个关于这方面的问题,但我想我找到了问题的根源。C:免费获得比我想要的更多的空间
我有一个包含该循环的程序mainLex.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
}
通过循环运行一次后,该方法应该是自由空闲列表清单,然后要求新的字符串作为使用名单。这一切都很好,但我发现freeList释放了我没有要求的东西!特别是,它释放了全局静态数据结构llist,我不确定这是如何发生的。
为空闲列表的代码:
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(我需要打扫一下了很多,但它的功能,截至目前)
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 2014-10-22 07:42:21