无论我做什么,snprintf()都会给我一个分段错误

时间:2012-08-15 14:50:24

标签: c segmentation-fault printf

所以我搜索并查看了所有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的理解,这应该有效。事实上,它实际上是在昨天下午工作,但突然间它在昨晚深夜开始出现故障。 :(

2 个答案:

答案 0 :(得分:2)

这是一个可能的原因:

printf("[%s] [%s] %30s (other)\n",
       (char*) S_ISREG(statBuffer.st_mode),
       (char *)statBuffer.st_mode,
       yourFileName);

这指示printf()

  • S_ISREG()的返回值视为指向空终止字符串的指针,它不是01(基于以下从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作为格式说明符而不是%sS_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和朋友(putsfputs)输出字符串。