【问题标题】:Unknown behavior with C functions (fgets, scanf, fread, fwrite, fopen)C 函数(fgets、scanf、fread、fwrite、fopen)的未知行为
【发布时间】:2012-03-06 01:32:13
【问题描述】:

我目前正处于我的计算机工程高级项目的最终开发和测试阶段。在使用库(Libjpeg、Libbmp、PocketSphinx、Libavcodec、Libavformat、Libavutil)并使用 netbeans 作为 IDE 进行代码(C、Bash)的设计和开发之后。我遇到的问题是,在 Netbeans 中,代码可以完美地编译和链接,并且软件的执行也很好。但是,当我使用 MakeFile 从外部编译和链接代码时,诸如:fopenfreadfwritefgetsfscanf 等函数停止工作...

GCC 标志:

-m32 -O3 -W -Wall -std=gnu99 -pedantic -Wbad-function-cast -Wcast-align -Wcast-qual \
-Wchar-subscripts -Winline -Wmissing-prototypes -Wnested-externs -Wpointer-arith \
-Wredundant-decls -Wshadow -Wstrict-prototypes -Wwrite-strings -Wformat-nonliteral \
-Wformat-security -ftrapv -lrt -Wno-unused \
-DMODELDIR=\"`pkg-config --variable=modeldir pocketsphinx`\" \
`pkg-config --cflags --libs pocketsphinx sphinxbase` \
`pkg-config --cflags --libs sndfile`

LD-FLAGS:

-I/usr/local/lib -I/usr/local/include -I/usr/local/lib/pkgconfig -lpthread \
-lpocketsphinx -lsndfile -ljpeg -lavformat -lavcodec -ldl -lasound -lz -lswscale \
-lavutil -lm

同样的未知行为也影响了现在无法打开 HMM 的 PocketSphinx 的性能。

非常感谢任何启发,因为我的最后一次演讲是下周。

--------- 更新 ----------

这是我的实际 MakeFile

.SUFFIXES: .o .c
.c.o: $(CC) -c $(CFLAGS) $<

# Compiler and Flags 
CC = gcc
CFLAGS = -m32 -O3 -W -Wall -std=gnu99 -pedantic -Wbad-function-cast -Wcast-align -Wcast-qual -Wchar-subscripts -Winline -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wredundant-decls -Wshadow -Wstrict-prototypes -Wwrite-strings -Wformat-nonliteral -Wformat-security -ftrapv -Wno-unused -DMODELDIR=\"`pkg-config --variable=modeldir pocketsphinx`\"`pkg-config --cflags --libs pocketsphinx sphinxbase` `pkg-config --cflags --libs sndfile`

# Libraries
LIBS = -I/usr/local/lib -I/usr/local/include -I/usr/local/lib/pkgconfig -lpocketsphinx -lsndfile -ljpeg -lavformat -lavcodec -ldl -lasound -lz -lswscale -lavutil -lm

# Source files
SRC= libbmp.c state.c secure.c audio.c config.c engine.c helpers.c macmp2.c queue.c image.c video.c

# Object Files
OBJ= libbmp.o state.o secure.o audio.o config.o engine.o helpers.o macmp2.o queue.o image.o video.o

# Executable file
EXECUTABLE = macmp2

# Explicit rule
hist: $(OBJ)
    $(CC) $(CFLAGS) -o $(EXECUTABLE) $(OBJ) $(LIBS)

clean:
    rm -f *.o
    rm -f $(EXECUTABLE)

# Implicit rules
audio.o: macmp2.h libbmp.h audio.c
config.o: macmp2.h libbmp.h config.c
engine.o: macmp2.h libbmp.h engine.c
helpers.o: macmp2.h libbmp.h helpers.c
image.o: macmp2.h libbmp.h image.c
libbmp.o: libbmp.h libbmp.c
macmp2.o: macmp2.h libbmp.h macmp2.c
queue.o: macmp2.h libbmp.h queue.c
secure.o: macmp2.h libbmp.h secure.c
state.o: macmp2.h libbmp.h state.c
video.o: macmp2.h libbmp.h video.c

编译时错误:无 运行时错误:无

我首先注意到这部分代码中的问题。

void load_configuration (macmp2_state * s)
{
    register uint32_t it = 0x0;                     /* Iterator */
    register uint32_t size = get_file_size (s);     /* Configuration File Size */
    char * new_entry = (char *) malloc_safe (sizeof (char) * LINE_LENGTH * 5, s);
    char * error_msg = (char *) malloc_safe (sizeof (char) * LINE_LENGTH * 5, s);
    char * filename = NULL;                         /* Filename Token */
    char * pmode = NULL;                            /* Processing Mode Token */
    char * token = NULL;                            /* String Token */
    FILE * fp = NULL;                               /* File Pointer */

    /* Temporary Variables */
    video_file * v = (video_file *) malloc_safe (sizeof(*v), s);
    image_file * i = (image_file *) malloc_safe (sizeof(*i), s);
    audio_file * a = (audio_file *) malloc_safe (sizeof(*a), s);

#ifdef DEBUG
    fprintf (stderr, "Reading configuration file.\n");
#endif

    fp = fopen_safe (s->config_file, "r", s);

    for (it = size; it > 0x0; it--)
    {
        /* Initializing Variables */
        memset (new_entry, '\0', LINE_LENGTH * 5);
        init_video_file (v);
        init_image_file (i);
        init_audio_file (a);

        /* Extracting entry from configuration file */        
        if (fgets (new_entry, (LINE_LENGTH * 5 * sizeof(char)), fp) == NULL)
        {
            fatal_error (s, "Error reading configuration file.");
        }

使用 MakeFile 编译时,我总是收到“读取配置文件错误”,但在 Netbeans 上却没有。

程序 输入:./macmp2 -c configuration.txt 输出:读取配置文件。

[*] 致命错误:读取配置文件时出错。

正如我所说,代码是我的高级项目,我不能在这里发布。我很确定这个问题与链接器标志有关。程序在第一次迭代时停止。正如我之前所说,代码在使用 Netbeans 编译时有效,但在使用发布的 MakeFile 编译时停止工作。

--------- 更新 ----------

应 Jonathan Leffler 的要求,这里是 fopen_safe 和 malloc_safe 的包装器。

fopen_safe 和 malloc_safe 的代码都是我自己实现的。

void * malloc_safe (size_t size, macmp2_state * s)
{
    void * ptr = malloc (size);

    if (ptr == NULL)
    {
        fatal_error (s, "Memory could not be allocated.");
    }
    return ptr;
}

FILE * fopen_safe (const char * filename, const char * mode, macmp2_state * s)
{
    FILE * stream = fopen (filename, mode);

    if (stream == NULL)
    {
        fatal_error (s, "Stream could not be open.");
    }
    return stream;
}

【问题讨论】:

  • 一周时间可能不够。如果在 Make 下构建是您项目的目标,那么您应该从一开始就这样做,而不是事后才想到。
  • “停止工作”不是我们可以帮助您的。如果您有编译时错误,请将其发布。如果您遇到运行时崩溃,请描述它。如果输出不是您所期望的,请详细说明输入。贴一些代码。
  • 请注意-I 标志会影响 C 预处理器,而不是链接器。在LDFLAGS 中列出它们可能无关紧要,但确实显示了一个概念问题。可以说,GCC 标志中列出的 pkg-config 的两个调用(包括 --libs)应该在 LDFLAGS 部分中。如果两者都使用,你会没事的。但是,当您在命令行上创建目标文件并指定库时,某些版本的 GCC 会抱怨(或者,更有可能是曾经抱怨过;我不记得几年来一直在抱怨)。 (GCC 标志中的 -lrt 也是一个库引用!)
  • 我用 MakeFile 的源代码更新了我的帖子。
  • 您的LIBS 的订单可能有误。另请阅读 GNU Make 的教程文档

标签: c linux netbeans makefile libavcodec


【解决方案1】:

您的链接标志(您的问题中的“ld-flags”)顺序错误。

链接器的程序参数顺序(ld,经常通过gcc 调用)很重要。您应该首先放置源文件(对于gcc),然后是目标文件(按依赖顺序),然​​后是库(从高级系统到低级系统)。例如,您的-lpthread 应位于-lavformat 之后

但是你真的应该学会写Makefile-s。不知道你有没有时间。好的做法是在项目开始时启动您的Makefile 并改进它(随着您改进代码)。

【讨论】:

    【解决方案2】:

    您的代码在这两种情况下都能正常编译(包括满足链接器)。

    然后你在这两种情况下运行它,在后者中,当你使用 make 构建它时,你会得到一个意想不到的结果。

    在我看来,这更像是您没有检查运行应用程序的环境。 fgets 的文档清楚地指出,NULL 不仅会在错误时返回,而且在遇到 EOF 时如果没有读取任何字节也会返回。

    如果您真的想知道打开了哪个文件,请使用 strace,并确保您在预期的环境中运行应用程序,并在适当的位置放置适当的配置文件。我相信这会让你发现问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-07
      • 1970-01-01
      • 2020-12-14
      • 1970-01-01
      • 2012-01-22
      • 2016-12-29
      • 1970-01-01
      相关资源
      最近更新 更多