变量中不明原因的垃圾值

时间:2012-03-30 18:11:45

标签: c memory bison flex-lexer

我试图通过在野牛中创建一个解析器来编译以下格式的文件

LOCATION house
NAME "House"
DESCRIPTION "You are standing\nin front of your house.\nPaths lead towards east and west."
east flag
west forest

LOCATION obelisk
NAME "Obelisk"
DESCRIPTION "A big obelisk is\nstanding before you. You can either go east or west or  south." 
south flag
east flag
west treasure

我的解析器有一个函数

int find(char *id) {
int i;
for(i=0;i<nLoc;i++) {
if(strcmp(id,tmp_idList[i]) == 0){
    printf(tmp_idList[0]);
    printf(" i = %d returned",i);
return i;

    }
}

printf("Copying...");
strcpy(tmp_idList[nLoc],id);
printf("%d %s",nLoc,tmp_idList[nLoc]);
nLoc++;
printf(" nloc-1 = %d returned",nLoc-1);
return (nLoc-1);
}

使用

char tmp_idList[60][100];

语法(相关)

locnSpec : tok_LOCN tok_IDENT nameSpec descrSpec exitList
            {int k = find($2);
             locList[k].name = strdup(tmp_name);
             locList[k].descr = strdup(tmp_descr);
             memcpy(locList[k].exits, 
                    tmp_exit,
                    4*sizeof(int));}

现在,当我运行此代码时,不知何故

 tmpidList[0] 

正在填充垃圾值,如输出

中所示
Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.



C:\Users\MY PC\Desktop\final>bison -d -o compile.c adv6.y

C:\Users\MY PC\Desktop\final>gcc -o compile compile.c lex.yy.c

C:\Users\MY PC\Desktop\final>compile<toy.al



 Copying...0 flag nloc-1 = 0 returned
 Copying...1 forest nloc-1 = 1 returned

Copying...2 house nloc-1 = 2 returned


 flag i = 0 returned // OK HERE
 flag i = 0 returned
 Copying...3 treasure nloc-1 = 3 returned

Copying...4 obelisk nloc-1 = 4 returned



Copying...5 marsh nloc-1 = 5 returned


 nd west. i = 4 returned // JUNK HERE
 Copying...6 flag nloc-1 = 6 returned
 nd west. i = 1 returned

nd west. i = 3 returned


 t. i = 4 returned
 t. i = 2 returned
 t. i = 4 returned

t. i = 6 returned


 t. i = 5 returned
 t. i = 2 returned
 t. i = 3 returned

t. i = 1 returned t. i = 2 returned


C:\Users\MY PC\Desktop\final>

当我尝试通过malloc分配内存时提示

char* tmp_idList[20]

...

tmp_idList[nLoc] = malloc(strlen(id) +1 )

它工作正常,直到tmp_idList [0]中有标志,但是停止工作并且compile.exe中存在内存错误。

有没有人知道发生了什么?如果你想了解更多信息,我可以提供。我真的需要帮助我的大学项目。

2 个答案:

答案 0 :(得分:1)

一个注意事项。您的find函数可能被称为intern。它的作用是将字符串标记减少为数字原子。如果之前没有看过字符串,它会返回一个新的原子,但是如果它用相同的字符串调用两次,它每次都会返回相同的原子。这称为实习,起源于Lisp语言。

你在代码中遇到了一些问题,因为你的符号有100个字符名称的空间,但是你没有检查它,只是使用盲目strcpy。

现在关于这个语法规则:

locnSpec:tok_LOCN tok_IDENT nameSpec descrSpec exitList                {int k = find($ 2);                 locList [k] .name = strdup(tmp_name);                 locList [k] .descr = strdup(tmp_descr);                 的memcpy(locList [K] .exits,                        tmp_exit,                        4 *的sizeof(INT));}

如果位置规范针对同一位置出现两次,该怎么办?你只是通过覆盖locList[k].name来泄漏这个记忆。您可能想要释放之前存在的旧值。如果将这些结构初始化为null / 0,则可以执行以下操作:

自由(locList [K]。名称);    locList [k] .name = strdup(tmp_name);

其次,这些tmp_nametmp_descr变量来自何处?在减少namesSpecdescrSpec非终结符号期间,这些全局变量是否被填充了值?

这是一种令人讨厌的方法;你真的应该使用Yacc堆栈来返回语义值,并通过$ 3,$ 4和$ 5来引用它们。

至于你追逐的腐败问题;它很可能是一个静态数组溢出。你没有做任何检查任何界限。

问题的关键在于:

/* two arrays, probably located side by side in the executable image */
static char array1[20][30];
static char array2[40][20];

如果您访问array1超出其结尾,则可能会删除其他变量,例如array2,具体取决于运行时映像中的布局方式。

在没有更高级的调试工具的情况下,您可以做的一件事是逐步调试调试器中的代码并监视覆盖变量的内容。试着抓住“红手”改变这个价值的程序。

其次,该删除数组的内容应该为您提供有关该材料来自何处的线索!它似乎是一个文本片段,可以追溯到您的输入,从那里您可以跟踪解析器中输入部分的处理位置。

答案 1 :(得分:0)

尝试

tmp_idList = malloc(strlen(id) +1 )

另外,我建议您使用C ++ string 类而不是 char *。对于没有完全理解C指针和内存分配的初学者来说,它更容易出错(就像你一样)。