Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Segmentation fault executing file writing using FILE pointer

Tags:

c++

c

file-io

I get a "Segmentation fault" for the following C++ code:

#include <cstdio>

int main(int, char**) {
  FILE *fp;
  fp = fopen("~/work/dog.txt", "w");
  fprintf(fp, "timer, timer3, timer5, timer6, timer7");
  fclose(fp);
}
like image 768
jdl Avatar asked Dec 26 '22 02:12

jdl


2 Answers

Your path is invalid and will never work, thus fopen sets fp to NULL and you get a segfault. Hint: the ~ character is expanded by the shell, you can't use it in an argument to fopen.

A correct, safe implementation of what you're trying to do might look as follows. This is tested. It's also the reason why sane people don't write in C unless they have no other way of doing it :)

// main.cpp
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>

int main(int, char**)
{
    const char * home = getenv("HOME");
    if (home == NULL || strlen(home) == 0 || access(home, F_OK) == -1) abort();
    const char * subPath = "/work/dog.txt";
    char * path = (char*)malloc(strlen(home) + strlen(subPath) + 1);
    if (path == NULL) abort();
    strcpy(path, home);
    strcat(path, subPath);
    FILE *fp = fopen(path, "w");
    if (fp != NULL) {
        fprintf(fp, "timer, timer3, timer5, timer6, timer7");
        fclose(fp);
    }
    free(path);
}
like image 112
3 revs Avatar answered Mar 15 '23 22:03

3 revs


A few things:

  • you need to check fp for NULL before using it, else you'll get a segfault whenever the file isn't found.

  • you need to resolve the full path before passing it to fopen (fopen doesn't know what to do with "~")

example:

FILE *fp = NULL;
char path[MAX];
char *home = getenv ("HOME");
if ( home ) 
{
    snprintf(path, sizeof(path), "%s/work/dog.txt", home);
    // now use path in fopen
    fp = fopen(path, "w");

    if ( fp )
    {
        fprintf(fp, "timer, timer3, timer5, timer6, timer7");
        fclose(fp);
    }
    else
    {
        std::cout << "your dog is missing" << std::endl;
    }
else
{
    std::cout << "You are homeless" << std::endl;
}
like image 24
ash Avatar answered Mar 15 '23 20:03

ash