【问题标题】:Segmentation fault when writing to file in c在c中写入文件时出现分段错误
【发布时间】:2017-11-11 21:50:52
【问题描述】:

我已经失去了希望和想法。我一直在尝试调试这个简单的代码,它应该在文件中创建一个简单的表,为期 3 天。运行它时,我总是遇到分段错误。我是 c 新手,但我知道分段错误是什么。我似乎无法在这里修复它。运行编译后的代码时,它确实创建了一个具有正确名称的空文件,但随后发生了错误,我保留了一个新但完全为空的文件。所以我猜这个问题在 fopen 和第一个 fprintf 之间。有什么想法吗?

#include <stdio.h>
#include <math.h>

void calc23(float x, float *f1, float *f2){
    *f1 = pow(x,2)-4.0*x+8.0;
    *f2 = pow(x,3)+2.0*x;
}

void main(){
    FILE *datf;
    datf = fopen("mydatatable.data", "w");
    float *f1, *f2;
    float r = -2.0;
    for(int i=1; i<100; i++){
        calc23(r, f1, f2);
        fprintf(datf, "%f %f %f \n", r, *f1, *f2);
        r += (4.0/99.0);
    }
    fclose(datf);
}

【问题讨论】:

  • 我可以问 f1、f2 并指向什么吗?你没有初始化它。结果和访问冲突(分段错误不是 Windows 字)
  • float f1, f2; calc23(r, &amp;f1, &amp;f2); fprintf(datf, "%f %f %f \n", r, f1, f2); 应该是
  • 该函数只有两个有效签名:main() 1) int main( void ) 和 2) int main( int argc, char *argv[] ) 无论 Visual Studio 允许什么
  • 函数:pow() 使用所有double 值。但发布的代码中的所有变量都是float 类型。您可以尝试使用powf() 并将所有文字更改为float 或将所有变量更改为double
  • 关于:float *f1, *f2; 这些被声明为指针,但它们从未设置为指向应用程序拥有的内存。到如下语句:*f2 = pow(x,3)+2.0*x; 正在设置一些随机内存位置(变量(f1 和 f2)所在的堆栈上发生了什么。这是未定义的行为,可能导致段错误事件。(如您所见)看过)

标签: c windows segmentation-fault


【解决方案1】:

您的指向 float f1f2 的指针未初始化。 使它们成为简单的浮点变量并使用地址运算符传递它们

float f1, f2;
calc23(x, &f1, &f2);
printf("..", f1, f2);

【讨论】:

  • 这确实有效,非常感谢您(以及评论相同的@RbMm)!我不明白为什么原始代码不起作用...
  • calc23() 中以 *f1 = pow... 开头的部分正在取消引用未初始化的指针,从而导致访问冲突。
  • 通过将&amp;f1 传递给函数,calc23 中的f1 是指向进程堆栈中某处的浮点变量的有效指针。
【解决方案2】:

以下建议的代码:

  1. 干净编译
  2. 不会出现段错误,因为没有未定义的行为会导致段错误
  3. 正确检查系统功能中的错误
  4. 记录包含每个头文件的原因
  5. 将cmets中列出的问题更正到问题中
  6. 选择使用powf() 而不是pow(),因此所有值(和文字)都具有float 类型

现在建议的代码:

#include <stdio.h>   // fopen(), fclose(), fwrite(), FILE
#include <stdlib.h>  // exit(), EXIT_FAILURE
#include <math.h>    // powf()

// prototypes
void calc23(float x, float *f1, float *f2);


int main( void )
{
    FILE *datf = fopen("mydatatable.data", "w");
    if( !datf )
    {
        perror( "fopen to write mydatatable.data failed");
        exit( EXIT_FAILURE );
    }

    // implied else, fopen successful

    float f1;
    float f2;
    float r = -2.0f;

    for(int i=1; i<100; i++)
    {
        calc23(r, &f1, &f2);
        fprintf(datf, "%f %f %f \n", r, f1, f2);
        r += (4.0f/99.0f);
    }
    fclose(datf);
}


void calc23(float x, float *f1, float *f2)
{
    *f1 = powf(x,2.f)-4.0f*x+8.0f;
    *f2 = powf(x,3.f)+2.0f*x;
}

程序输出的前几行:

-2.000000 20.000000 -12.000000 
-1.959596 19.678400 -11.444072 
-1.919192 19.360065 -10.907337 
-1.878788 19.044994 -10.389402 

程序输出的最后几行:

1.838385 4.026119 9.889888 
1.878789 4.014692 10.389421 
1.919193 4.006530 10.907358 
1.959597 4.001633 11.444093 

【讨论】:

  • 谢谢,这帮助我排查并解决了我的类似问题!
【解决方案3】:

简单调试代码: f1 和 f2 未初始化

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-14
    • 2018-08-06
    • 2021-06-14
    • 2012-01-03
    • 1970-01-01
    • 2022-10-04
    • 2019-03-27
    相关资源
    最近更新 更多