我正在为作业实施tail。我让它正常工作但是我似乎在随机时间免费获得错误。
我无法看到,将其追踪到一个模式或除此之外的任何事情都是一致的。
例如,如果我将程序称为“tail -24 test.in”,我会在多次运行的同一行中得到错误的校验和错误。但是,使用不同的文件,甚至不同的行数打印回来,我都会毫无错误地回来。
关于如何追踪问题的任何想法,我一直试图调试它几个小时无济于事。
以下是有问题的代码:
行被定义为char **,malloc为:
lines = (char**) malloc(nlines * sizeof(char *));
void insert_line(char *s, int len){
printf("\t\tLine Number: %d Putting a %d line into slot: %d\n",processed,len,slot);
if(processed > numlines -1){//clean up
free(*(lines+slot));
*(lines + slot) = NULL;
}
*(lines + slot) = (char *) malloc(len * sizeof(char));
if(*(lines + slot) == NULL) exit(EXIT_FAILURE);
strcpy(*(lines+slot),s);
slot = ++processed % numlines;
}
答案 0 :(得分:7)
您的例程正在写入超出分配的行缓冲区。
作为参数传递的行的大小(即“len”)可能不包括NUL终止符。当你调用malloc复制行(即“s”)时,你需要为字符串终止符分配一个额外的字节:
*(lines + slot) = (char *) malloc((len + 1) * sizeof(char));
答案 1 :(得分:3)
如果您可以使用特定输入参数一致地重现问题,则应按以下方式进行调试:
请注意,问题很可能与您的程序完全不同。即使报告错误是免费的,覆盖保护块的代码也可以在任何地方。
答案 2 :(得分:1)
我的第一个问题是你如何计算len?它只是strlen还是包含\ 0终止符的空间?我认为你可能会在你的strcpy中超出你的分配。不良行为往往会出现在单词边界上并且随机出现。另外,请检查以确保源字符串为空终止。如果你在阅读方面犯了错误并且没有终止它们。然后strcpy可能会随机覆盖一些东西。
*(lines + slot) = (char *) malloc(len * sizeof(char));
if(*(lines + slot) == NULL) exit(EXIT_FAILURE);
strcpy(*(lines+slot),s);
也许试试:
lines[slot] = (char *) malloc((len + 1) * sizeof(char));
if(lines[slot] == NULL) exit(EXIT_FAILURE);
if(strlen(s) <= len){
strcpy(lines[slot],s);
}
else{
/* do something else... */
}
就一般形式而言,我还鼓励你做一些风格上的改变,使整个事情更具可读性,更容易理解,并且能够抵御错误。
指针算法是有效且有趣的,但我认为如果使用数组形式,你的意图会更清晰:
free(lines[slot]);
lines[slot] = NULL;
而不是
free(*(lines+slot));
*(lines + slot) = NULL;
我也鼓励你使用更少的静力学。在数据结构中通过它们很容易,并将它们传递给您的访问器和更改器。事情发生的地方变得更加清楚,这会妨碍你做以下事情:
static int numlines = 0;
void insert_line(char *s, int len){
int numlines = 5;
您可以在其中介绍仅对调试感到悲惨的范围问题。
答案 3 :(得分:0)
nlines和numlines是否具有相同的值?
在第二个参数中传递长度时,insert_line的调用者是否允许尾随NUL的空间?
答案 4 :(得分:0)
我不确定它是否相关,但这两行对我来说似乎很可疑:
*(lines + slot) = (char *) malloc(len * sizeof(char));
if((lines + slot) == NULL) exit(EXIT_FAILURE);
首先将malloc的返回值分配给lines[slot]
,然后检查(lines+slot)
,如果后者为NULL,则取消引用NULL指针!
如果行[slot](你的*(行+插槽))不为null,当你将malloc()的结果赋给它时,你将泄漏内存。
我认为lines
是char
*行[]`并且插槽位于允许的边界内!
答案 5 :(得分:0)
我同意雷莫对这两条线的怀疑,但不同意雷莫的切线。我们应该分享信用来发现这个错误。
*(lines + slot) = some value
if((lines + slot) == NULL) then die
should be
if(*(lines + slot) == NULL) then die