C 服务器上的分段错误,但本地计算机上的分段错误

C 服务器上的分段错误,但本地计算机上的分段错误,c,segmentation-fault,C,Segmentation Fault,如标题所述,该程序在我的本地机器(ubuntu 9.10)上运行,但在服务器(linux)上不运行。这是godaddy的一个网格托管包 请帮忙 代码如下: #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { long offset; FILE *io; unsigned char found; unsigned long loc; if

如标题所述,该程序在我的本地机器(ubuntu 9.10)上运行,但在服务器(linux)上不运行。这是godaddy的一个网格托管包

请帮忙

代码如下:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    long offset;
    FILE *io;
    unsigned char found;
    unsigned long loc;

    if (argc != 2)
    {
        printf("syntax: find 0000000\n");
        return 255;
    }

    offset = atol(argv[1]) * (sizeof(unsigned char)+sizeof(unsigned long));

    io = fopen("index.dat","rb");
    fseek(io,offset,SEEK_SET);
    fread(&found,sizeof(unsigned char),1,io);
    fread(&loc,sizeof(unsigned long),1,io);

    if (found == 1)
        printf("%d\n",loc);
    else
        printf("-1\n");

    fclose(io);

    return 0;
}
#包括
#包括
int main(int argc,字符**argv)
{
长偏移量;
文件*io;
找到未签名字符;
无符号长loc;
如果(argc!=2)
{
printf(“语法:find 0000000\n”);
返回255;
}
offset=atol(argv[1])*(sizeof(无符号字符)+sizeof(无符号长字符));
io=fopen(“索引数据”、“rb”);
fseek(io、偏移、寻道设置);
fread(&found,sizeof(unsigned char),1,io);
fread(&loc,sizeof(无符号长),1,io);
如果(找到==1)
printf(“%d\n”,loc);
其他的
printf(“-1\n”);
fclose(io);
返回0;
}
编辑:这不是我的节目。 我希望我知道足够的C来修复它,但我已经到了最后期限了。此程序旨在查找PI序列中第一个出现的7位数字,index.dat包含一个巨大的数组编号=>位置

编辑2:我将更新后的代码与空指针测试一起使用,仍然得到相同的结果。
程序在我的本地计算机上运行正常,此错误仅发生在服务器上。

也许您应该尝试为find和loc变量分配一些内存?

首先,您没有给我们错误发生的上下文


第二,在人们花时间在它上面之前,你需要添加错误检查。

最有可能的事情是,fopen出现了故障-你没有检查它的返回值,看你是否真的得到了一个有效的指针。(当您尝试在下一行中使用空指针时,会出现SEGFULT。)

可能“index.dat”不在您的服务器上,但在您的计算机上。因为你是用“rb”打开它的,并且没有在fopen之后检查io,所以很可能会这样做。

我最初的猜测是文件无法打开,因此io是空的


但是韦德是对的:您应该首先在程序中添加一些错误处理,至少这会让您(和我们)更好地了解出了什么问题。

将代码的中间部分更改为:

fseek(io,offset,SEEK_SET);
printf("fseek worked\n");
fread(&found,sizeof(unsigned char),1,io);
printf("fread 1 worked\n");
fread(&loc,sizeof(unsigned long),1,io);
printf("fread 2 worked\n");
并查看运行程序时打印的行。这应该给你一个提示,问题到底出在哪里


Edit:当我说函数调用“已工作”时,我的意思是“未导致故障”。理想情况下,您应该检查对
fseek
fread
的每个调用,以确保它们没有遇到任何错误,但您提到您正处于截止日期,因此这只是一些快速的错误跟踪,以尝试跟踪segfault。

您能在服务器上运行gdb吗?如果是这样,则在启用调试的情况下构建(-g选项到gcc)并在gdb中运行它。这将告诉你程序失败的地方。以下是如何(用相关信息替换中的内容):

#gdb
(gdb)设置参数
(gdb)运行

gdb将捕获SEGFULT并显示故障线路

我猜服务器上的
sizeof(long)
是8(因为它是64位系统),而本地机器上是4(假设是32位机器)。因此,计算到文件中的偏移量将错误2倍。如果需要转到文件中的特定偏移量,则应使用固定大小类型,即
uint32\u t
等。

可能机器上的
无符号长
的大小不同

以下程序在您的机器上打印什么

#include <stdio.h>

int main(void)
{
    printf("%zu\n", sizeof(unsigned long));
    return 0;
}
以上假设“正常工作”程序有4字节
无符号长
。如果没有,则需要将程序中的
4
替换为正确计算机上的
unsigned long
的大小


如果这就是差异的原因,那么您现在知道了读取和写入二进制数据的一个问题:您必须非常小心大小、endianness等。

我认为您的读取超出了文件限制。我添加了一部分来检查文件大小,并确保您在文件限制内读取

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    long offset;
    FILE *io;
    unsigned char found;
    unsigned long loc;

    if (argc != 2)
    {
        printf("syntax: find 0000000\n");
        return 255;
    }

    offset = atol(argv[1]) * (sizeof(unsigned char)+sizeof(unsigned long));

    io = fopen("index.dat","rb");
if (io==NULL) {fputs ("File error",stdout); exit (1);}
fseek (io , 0 , SEEK_END);
long fileSize = ftell (io);
long offsetEnd = offset+sizeof(unsigned char)+sizeof(unsigned long);
printf("file size: %d\nseek: %d\nseekEnd: %d\n",fileSize,offset,offsetEnd);

if (offsetEnd> fileSize) {fputs ("Reading outside of file...",stdout); exit (1);}

    fseek(io,offset,SEEK_SET);
    fread(&found,sizeof(unsigned char),1,io);
    fread(&loc,sizeof(unsigned long),1,io);

    if (found == 1)
        printf("%d\n",loc);
    else
        printf("-1\n");

    fclose(io);

    return 0;
}
#包括
#包括
int main(int argc,字符**argv)
{
长偏移量;
文件*io;
找到未签名字符;
无符号长loc;
如果(argc!=2)
{
printf(“语法:find 0000000\n”);
返回255;
}
offset=atol(argv[1])*(sizeof(无符号字符)+sizeof(无符号长字符));
io=fopen(“索引数据”、“rb”);
如果(io==NULL){fputs(“文件错误”,标准输出);退出(1);}
fseek(io,0,SEEK_END);
长文件大小=ftell(io);
long offsetEnd=offset+sizeof(无符号字符)+sizeof(无符号长字符);
printf(“文件大小:%d\n seek:%d\n sekend:%d\n”,文件大小、偏移量、偏移量);
如果(offsetEnd>fileSize){fputs(“读取文件外部…”,stdout);退出(1);}
fseek(io、偏移、寻道设置);
fread(&found,sizeof(unsigned char),1,io);
fread(&loc,sizeof(无符号长),1,io);
如果(找到==1)
printf(“%d\n”,loc);
其他的
printf(“-1\n”);
fclose(io);
返回0;
}

我刚在godaddy上遇到这个问题,发现FTP客户端是用ASCII而不是二进制上传的。上传之前,我将扩展名改为
.bin
,现在工作正常。

故障信息是什么?哪一行失败?可能文件不在那里,所以
fopen
返回NULL?为什么要将参数乘以(sizeof(long)+sizeof(char))以获得偏移量?。。。如果对fopen的调用起作用,这将使您通过文件的结尾-您是否确实首先验证了这一点…如果参数是1234567呢????哦,是的,在继续之前先打开文件时检查NULL…下面的评论中提到的另一件事…您将其上载到服务器,服务器上的文件名也可能区分大小写?Index.DAT与Index.DAT区分大小写…首先检查…文件名与代码中的文件名完全相同。found和loc位于堆栈上。这不是答案。这是一个comment.Spe
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <stdint.h>

int main(int argc, char **argv)

{
    long offset;
    FILE *io;
    unsigned char found;
    uint32_t loc;

    if (argc != 2)
    {
        printf("syntax: find 0000000\n");
        return 255;
    }
    /* sizeof(unsigned char) is 1, and I am assuming you wanted
       sizeof(unsigned long) to be 4.  But see below. */
    offset = strtol(argv[1], NULL, 0) * (1+4);

    if ((io = fopen("index.dat", "rb")) == NULL) {
        fprintf(stderr, "Cannot open file\n");
        return EXIT_FAILURE;
    }
    if (fseek(io, offset, SEEK_SET) == -1) {
        fprintf(stderr, "Error seeking\n");
        perror(NULL);
        return EXIT_FAILURE;
    }
    if (fread(&found, 1, 1, io) != 1) {
        fprintf(stderr, "Error in first fread\n");
        return EXIT_FAILURE;
    }
    /* using sizeof loc makes sure that the correct size if always used,
       irrespective of the type of loc */
    if (fread(&loc, sizeof loc, 1, io) != 1) {
        fprintf(stderr, "Error in second fread\n");
        return EXIT_FAILURE;
    }
    if (found == 1)
        printf("%" PRIu32 "\n", loc);
    else
        printf("-1\n");
    fclose(io);

    return 0;
}
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    long offset;
    FILE *io;
    unsigned char found;
    unsigned long loc;

    if (argc != 2)
    {
        printf("syntax: find 0000000\n");
        return 255;
    }

    offset = atol(argv[1]) * (sizeof(unsigned char)+sizeof(unsigned long));

    io = fopen("index.dat","rb");
if (io==NULL) {fputs ("File error",stdout); exit (1);}
fseek (io , 0 , SEEK_END);
long fileSize = ftell (io);
long offsetEnd = offset+sizeof(unsigned char)+sizeof(unsigned long);
printf("file size: %d\nseek: %d\nseekEnd: %d\n",fileSize,offset,offsetEnd);

if (offsetEnd> fileSize) {fputs ("Reading outside of file...",stdout); exit (1);}

    fseek(io,offset,SEEK_SET);
    fread(&found,sizeof(unsigned char),1,io);
    fread(&loc,sizeof(unsigned long),1,io);

    if (found == 1)
        printf("%d\n",loc);
    else
        printf("-1\n");

    fclose(io);

    return 0;
}