0

I started writing some code (see below) and when I tried running it (gcc file.c; ./a.out) I got a segfault and I don't understand why. If I comment out

free(filename); // or
double *data = ...;

there's no segfault. What's going on? I didn't know what to search for but I found this question and followed the GDB instructions in the third answer. I don't understand the output (I've never used GDB or any other debugger) but maybe you do. (gdb) r

Program received signal SIGSEGV, Segmentation fault.│
0x00007ffff7a97d3c in __GI___libc_free (mem=0x7fffffffe5a0) at malloc.c:2945
2945    malloc.c: No such file or directory.

(gdb) bt

#0  0x00007ffff7a97d3c in __GI___libc_free (mem=0x7fffffffe5a0) at malloc.c:2945
#1  0x00000000004006a5 in main ()

Oh and doing away with the arg_handler doesn't make a difference.

EDIT: Code:

//#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//#include "graphics/graphics.c"
//#include "file_operations/file_operations.c"

#define ARGS 6
#define EPS 1e-03
#define DATA_LEN 5

int arg_handler(int ac, char *args[], int *a, char *b, int *c, double *d, double *e, int *f);

int main(int argc, char *argv[]) {

  int N, nsteps, graphics;
  char *filename;
  double dt, theta_max;
  if (arg_handler(argc, argv, &N, filename, &nsteps, &dt, &theta_max, &graphics)) {
    printf("Usage: ...\n");
    free(filename);
    return -1;
  }

  if (graphics) {
    printf("Graphics not available.\n");
    graphics = 0;
  }

  double *data = malloc(N*DATA_LEN*sizeof(double));
/*
  if (read_doubles_from_file(N*DATA_LEN, data, filename)<0) {
    perror("An error occured:\n");
    return -1;
  }
*/

//  free(data);

  return 0;
}

int arg_handler(int ac, char *args[], int *a, char *b, int *c, double *d, double *e, int *f) {

  if (ac!=1+ARGS) {
    return 1;
  }
  *a = atoi(args[1]);
  b = args[2];
  *c = atoi(args[3]);
  *d = atof(args[4]);
  *e = atof(args[5]);
  *f = atoi(args[6]);
  return 0;
}
Community
  • 1
  • 1
Erik Vesterlund
  • 481
  • 6
  • 19

1 Answers1

3

Your free(filename) call has no corresponding malloc() call; the filename pointer is coming from the argument vector. This memory doesn't have to be freed and is managed by the os when it starts a process.

Basically, your process is trying to free memory the os owns; therefore, the os prevents you from doing that and signals you so.

 // (1) >> unitialized pointer, cannot be freed.
 char *filename;

 double dt, theta_max;
 if (arg_handler(argc, argv, &N, filename, &nsteps, &dt, &theta_max, &graphics)) {
     printf("Usage: ...\n");
     // (3a) >> freeing memory owned by the os.
     // (3b) >> or freeing uninitialized pointer.
     free(filename);
     return -1;
 }

int arg_handler(int ac, char *args[], int *a, char *b, int *c, double *d, double *e, int *f) {
    if (ac!=1+ARGS) {
        // (2b) >> never initializing pointer
        return 1;
    }

    *a = atoi(args[1]);
    // (2a) >> setting value to a pointer managed by the os.
    b = args[2];
    *c = atoi(args[3]);
    *d = atof(args[4]); 
    *e = atof(args[5]);
    *f = atoi(args[6]);
    return 0;
}
Jazzwave06
  • 1,883
  • 1
  • 11
  • 19
  • Alright that makes sense. Only malloc:ed variables need to be freed... Do you know why it worked to comment out double *data? (while keeping free(filename)) – Erik Vesterlund Feb 18 '17 at 04:03
  • Nope, you might have to run valgrind to know for sure. – Jazzwave06 Feb 18 '17 at 04:09
  • 1
    @ErikVesterlund It didn't work. You had the set the same trap and corrupted the same structures, you just hadn't fallen into it yet. – David Schwartz Apr 26 '17 at 00:38
  • @DavidSchwartz I don't know what you're referring to? – Erik Vesterlund Apr 26 '17 at 16:20
  • @ErikVesterlund Once you corrupt the heap, it's like a land mine. Some innocent code is going to step on it and blow up. Without the innocent code, you don't see the explosion. But the corruption has still happened. That can make heap corruption very difficult to debug -- the crash appears to happen in perfectly innocent code. – David Schwartz Apr 26 '17 at 18:24
  • 1
    @DavidSchwartz Ok I got you now, I had to look at this problem again, had forgotten what it was about. Trying to free "filename" corrupted the heap, anything could have triggered the "land mine", in this case it was the allocation of "data"; commenting it out didn't make anything work, it just removed the trigger. Gotcha. – Erik Vesterlund Apr 27 '17 at 15:21