C 服务器上的分段错误,但本地计算机上的分段错误
如标题所述,该程序在我的本地机器(ubuntu 9.10)上运行,但在服务器(linux)上不运行。这是godaddy的一个网格托管包 请帮忙 代码如下: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
#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;
}