fprintf中指针的分段错误

时间:2014-08-11 20:16:08

标签: c fortran fortran77

我正在尝试运行一个程序,该程序接受输入文件,读取它,然后根据输入文件中指定的参数运行模拟。代码是C和Fortran77的混合,主要可执行文件完全在Fortran77中。我没有编写代码,而且我对两种语言都没有经验(所以如果我说一些愚蠢的话,那就是原因)。

运行程序后,无论输入文件是什么,我都会收到以下错误:Segmentation fault (core dumped)

这是我从valgrind得到的输出,有一些小的遗漏:

Invalid read of size 4
at 0x55ACFDD: vfprintf (vfprintf.c:1295)
by 0x55B76B6: fprintf (fprintf.c:32)
by 0x578C64: cfprintf_ (in [path omitted])
by 0x56D288: writebuf_ (writebuf.F:22)
by 0x56D3CC: writemsg_ (writemsg.F:15)
by 0x4C09E7: init0_ (init0.F:68)
by 0x4D6C65: [omitted]
by 0x4E9EC4: main (main.c:113)
Address 0xffffffff0592bbc0 is not stack'd, malloc'd or (recently) free'd


Process terminating with default action of signal 11 (SIGSEGV)
Access not within mapped region at address 0xFFFFFFFF0592BBC0
at 0x55ACFDD: vfprintf (vfprintf.c:1295)
by 0x55B76B6: fprintf (fprintf.c:32)
by 0x578C64: cfprintf_ (in [path omitted])
by 0x56D288: writebuf_ (writebuf.F:22)
by 0x56D3CC: writemsg_ (writemsg.F:15)
by 0x4C09E7: init0_ (init0.F:68)
by 0x4D6C65: [omitted]
by 0x4E9EC4: main (main.c:113)
If you believe this happened as a result of a stack
overflow in your program's main thread (unlikely but
possible), you can try to increase the size of the
main thread stack using the --main-stacksize= flag.
The main thread stack size used in this run was 8388608.

HEAP SUMMARY:
 in use at exit: 11,354 bytes in 7 blocks
total heap usage: 46 allocs, 39 frees, 22,590 bytes allocated

LEAK SUMMARY:
definitely lost: 0 bytes in 0 blocks
indirectly lost: 0 bytes in 0 blocks
possibly lost: 8,008 bytes in 2 blocks
still reachable: 3,346 bytes in 5 blocks
suppressed: 0 bytes in 0 blocks
Rerun with --leak-check=full to see details of leaked memory

For counts of detected and suppressed errors, rerun with: -v
ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

vfprintf.cfprintf.c文件似乎是某个内部库的一部分,因为我无法在计算机上找到这些文件。 cfprintf.c是我的代码的一部分,如下所示:

#include <stdio.h>
#include <fcntl.h>

#ifdef _CRAY
#ifdef FORTRAN_PASSES_ASSUMED_CHAR_LEN 
int CFPRINTF (fileptr, s1, cl1, num_chars)
int *cl1;
#else 
int CFPRINTF (fileptr, s1, num_chars)
#endif 
#else
#ifdef POST_UNDERSCORE
int cfprintf_ (fileptr, s1, num_chars)
#else
int cfprintf (fileptr, s1, num_chars)
#endif
#endif

/* write num_chars characters from string s1 to file associated with fileptr */
FILE **fileptr;
char *s1;
int *num_chars;

{
  char format_string [11];
  char buffer[256];
  sprintf (format_string, "%c.%ds", '%', *num_chars);

  /* write to an intermediate buffer to avoid problems with '\n' */
  sprintf (buffer, format_string, s1);
  fprintf (*fileptr, "%s\n", buffer);
}

引发错误的行是fprintf (*fileptr, "%s\n", buffer); 具体来说,我认为它是导致错误的指针,但我不是什么错误或如何解决它。

我最初编译代码时遇到了问题,因为我使用的是64位计算机。该代码严重依赖于指针,隐式声明了许多(如果不是全部的话),所以我认为这意味着它们采用默认的32位格式的4位整数。但是,在我的机器上,这些指针是8位整数,因为我用64位编译。

如果*fileptr是一种格式,但代码期望另一种格式,也许这就是从valgrind生成Invalid read of size 4消息的原因?但就像我说的那样,如果这就是问题,我仍然不知道如何解决它。

感谢您的帮助,如果我要发布任何其他代码,请告诉我。

2 个答案:

答案 0 :(得分:1)

首先,你绝对不应该像运行那样在运行时构建格式字符串。请改用以下内容:

snprintf(buffer, 256, "%.*s", *num_chars, s1);

甚至只是

fprintf(*fileptr, "%.*s\n", *num_chars, s1);

.*允许动态指定字符串的宽度。

接下来,我会检查您的fileptr是否有效,以及是否已成功打开。由于四个高字节都是0xffffffff0592bbc0,地址0xff非常可疑,因此您可能遇到32位/ 64位问题。

答案 1 :(得分:0)

正如我从你的问题中所理解的那样,应用程序已经知道在过去工作,但是在32位Unix系统上编译? (这是我在单个程序中混合使用旧Fortran和C代码的唯一环境。)

除非您想port the application to 64-bit,否则我建议您将其简单地编译为32位本机应用程序,假设您的操作系统允许32位应用程序在64位环境中运行。

例如,使用gcc编译器,您需要为64位x86处理器系统添加标志-m32。我相信clang支持相同的标志,但如果没有,请查看文档。

第二个可能的复杂因素是程序/应用程序(或其数据)是否为endian dependent,如果是在假设在大型ENDIAN CPU上运行(例如多数)而写的,这可能是一个问题使用RISC风格的处理器(MIPS,PowerPC等)的Unix工作站,你现在正试图在64位x86 Intel或AMD处理器(又名amd64,x86-64)上运行它。

我在这种情况下的建议是伤害某人 ......,呃,检查一下应用程序的重要性及其用法。

相关问题