所以我搜索并查看了所有snprintf(),sprintf()和分段错误线程,但仍然无处...
基本上,似乎仅仅存在snprintf()语句会导致我的代码出现分段错误。简而言之,是的,这是作业...基本上,我必须填写缺少的代码,并严格命令不要触摸已经存在的代码。这是我的代码的样子:
struct dirent* dirEntryPtr;
struct stat statBuffer;
char *yourFileName;
while((dirEntryPtr=readdir(dirPtr))!=NULL)
{
int yourFileSize;
memset(buffer,'\0',sizeof(buffer));
yourFileName=dirEntryPtr->d_name;
printf("Directory entry read...%s\n",yourFileName);
snprintf(buffer,MAX_LINE,"%s/%s",DIR_NAME,yourFileName);
printf("Printed directory entry to buffer...\n");
stat(buffer,&statBuffer);
yourFileSize=statBuffer.st_size;
printf("File size: %d\n",yourFileSize);
if(S_ISREG(statBuffer.st_mode))
{
printf("REGULAR!\n");
snprintf(buffer,MAX_LINE,"%30s (%5d)\n",yourFileName,yourFileSize);
printf("[%s] %30s (%5d)\n",(char *)statBuffer.st_mode,yourFileName,yourFileSize);
}
else
if(S_ISDIR(statBuffer.st_mode)){
printf("DIRECTORY!\n");
snprintf(buffer,MAX_LINE,"%30s (dir)\n",yourFileName);
printf("[%s] %30s (dir)\n",(char *)statBuffer.st_mode,yourFileName);}
else
{
printf("OTHER!!\n");
snprintf(buffer,MAX_LINE,"%30s (other)\n",yourFileName);
printf("[%s] [%s] %30s (other)\n",(char*) S_ISREG(statBuffer.st_mode),(char *)statBuffer.st_mode,yourFileName);
}
printf("Writing buffer \"%s\" to client...\n",buffer);
write(clientDescriptor,buffer,MAX_LINE);
free(buffer);
}
close(clientDescriptor);
exit(EXIT_SUCCESS);
所有的printf()都基本上用于调试。 (是的,我知道,使用GDB,但是尽管多年的教学,我仍然无法弄清楚这个东西是如何运作的!)
长话短说,一次一个地读入当前目录中的文件。第一个文件通常是一个名为server.c的文件,它始终被正确识别为“常规”文件。然而,当snprintf()行进入时,分段错误发挥作用。 buffer是一个声明的字符串(我不允许触摸的代码的一部分,但是指令专门用snprintf()将条目写入“buffer” - 事实上,我正在使用的EXACT snprintf()命令是指令中给出的!)并设置为MAX_LINE字节(80),它是在包含的外部头文件中的#defined。我之前有一个strnlen用于调试目的,以确认DIR_NAME是一个字符而yourFileName,至少在server.c的情况下,是9 - 远不及80!
我甚至尝试声明一个新变量,只是通过snprintf()写一个字节,但仍然出现了分段错误!无论是否使用malloc()命令,我都尝试过。
我还应该寻找什么?我确实通过电子邮件向我的教授发送了关于此的信息,但事实上,我必须提交这个,比如今天(它不会再过几天,但我将要离开城镇)并且需要尽快指点......但根据我对C的理解,这应该有效。事实上,它实际上是在昨天下午工作,但突然间它在昨晚深夜开始出现故障。 :(
答案 0 :(得分:2)
这是一个可能的原因:
printf("[%s] [%s] %30s (other)\n",
(char*) S_ISREG(statBuffer.st_mode),
(char *)statBuffer.st_mode,
yourFileName);
这指示printf()
:
将S_ISREG()
的返回值视为指向空终止字符串的指针,它不是0
或1
(基于以下从sys/stat.h
):
#define __S_ISTYPE(mode, mask) (((mode) & __S_IFMT) == (mask))
#define S_ISREG(mode) __S_ISTYPE((mode), __S_IFREG)
将st_mode
视为指向空终止字符串的指针(AFAIK,st_mode
的类型为int
)
要修复已使用的%d
作为格式说明符而不是%s
或S_ISREG()
,您可以使用三元运算符并返回字符串文字:
printf("[%s] [%d] %30s (other)\n",
S_ISREG(statBuffer.st_mode) ? "regular file" : "not regular file",
statBuffer.st_mode,
yourFileName);
这是一个错误,几乎可以肯定是原因:
char buffer[MAX_LINE];
free(buffer);
只传递给动态分配的free()
:
free函数导致ptr指向的空间被释放,即被释放 可供进一步分配。如果ptr是空指针,则不执行任何操作。否则,如果 参数与之前由calloc,malloc或realloc函数返回的指针不匹配,或者如果通过调用free或realloc释放了空间, 行为未定义。
答案 1 :(得分:1)
另一个错误:
write(clientDescriptor,buffer,MAX_LINE);
如果buffer
指向NUL终止字符串,那么几乎肯定不是您想要的。这总是写MAX_LINE
个字符,不会停留在NUL。我建议fprintf
和朋友(puts
,fputs
)输出字符串。