【问题标题】:fopen get error with char * in c++fopen 在 C++ 中使用 char * 获取错误
【发布时间】:2011-12-12 12:05:36
【问题描述】:

有一个加载文件的功能:

int loadfile(char *fn)
{
    printf( "\n my path: '%s' \n", fn );
    FILE *f = fopen( fn, "r");
    printf( "got\n" );

    ...

    return 1;
}

第一个文件在 main() newfile( argv[1] );,有效。第二个是通过弹性解析/读取第一个文件来获取,我相信与问题无关。

控制台:

path: 'file1.hot' 
got
path: 'file2.hot' 
Segmentation fault: 11

printf 能够打印 char *fn,但 fopen 出现分段错误。

接下来的情况是,我尝试将文件显式放入 loadfile 中并执行 fopen( "file2.hot", "r"); 并且可以正常工作。

我是用g++编译的,用c++用char *还是fopen有不同的处理方式?

编辑

抱歉,没有newfile( argv[1] );。正确:loadfile( argv[1] );

【问题讨论】:

  • 对于segfault的错误,你可能要给出完整的程序,而不是单个函数。错误通常不在弹出段错误的位置。
  • 发现问题有进展吗?您是否尝试过任何建议的解决方案?

标签: c++ c char


【解决方案1】:

一般说明:使用C++时,请优先使用std::fstream而不是C风格的fopen/fread/等;也更喜欢std::stringchar*。仅后者就可以治愈许多记忆问题。如果您出于某种原因必须坚持使用 C 风格的函数,请务必检查返回值(如此处其他答案中所述) - 例如,fopen 在失败时返回 NULL 指针。

更具体到您的问题:尝试在gdb(例如gdb <your-program>)下运行您的程序,以查看分段错误的确切位置;这样您还可以查看更多详细信息(例如变量内容等)。或者,如果在 linux 下工作,请使用 valgrind 等分析工具来检测任何类型的内存访问问题。

【讨论】:

  • 也许更重要的是:更喜欢std::string 而不是char*。我敢打赌他的问题是由于使用char*时缓冲区溢出造成的。
  • 是的,我更喜欢,但这个小部分在 gnu-flex 中。不知道能不能改成fstream和string。
  • '我曾经相信 printf,然后我拿了一个......'。正如你们所有人所说,问题出在另一部分。我现在正确地使用gdb。我不明白为什么没有打印 printf,因为真正的问题远非如此。
  • 可能是因为printf输出被缓冲了;据我所知,您必须在每次调用 printf 后调用 fflush(stdout) 以使其立即打印。
【解决方案2】:

您应该始终检查具有返回值的函数的返回值。在这种情况下,请确保在打开文件时返回句柄不为 NULL,并确保在打开文件时关闭它。

【讨论】:

    【解决方案3】:

    学习使用GDB 调试器(假设您在Linux 上)或valgrind 实用程序。 也许将您的文件路径放在std::string 中是值得的,并且正如nyarlathotep 提到的,使用std::fstream

    您的fn 可能不会以空值终止....

    使用g++ -Wall -g编译

    正如Anders K 回答的那样,始终检查fopen 的结果是否为NULL。 Pierre Vittet 对 GCC 的 Talpo 扩展(编码为 MELT)能够自动检查您是否进行了检查。

    【讨论】:

    • 如果程序在加载文件时出现分段错误,问题可能出在其他地方,而不是那里?步骤是 print-name > fopen > print-got。如果得到的打印件没有打印,问题可以也不能在打印件之间?我按照你说的编译,0点是<????>,序列在另外一个地方,我无法弄清楚连接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多