views:

294

answers:

5

Hi!

I'm rewriting an old program to do some new stuff, and suddenly I get a segmentation fault error on the following line of code:

time_t seconds_since_time_begun = time(0);

Why, oh why?

Update:
I have included the time.h header file in my code, and when I tried what pmg suggested below, both variables were 4 in size.

When I tried the following:

printf("4\n");
// time_t seconds_since_time_begun = time(0);
printf("5\n");

I still get segmentation fault right after "4" has been printed, even when the line where time() is called is commented out. "5" is not outputted. How is this possible?

Update 2:
I rebuilt my function step by step to try to isolate where the error occurred in my code, and I think I found the problem. I'm not sure what was wrong but it had something to do with a comparison between an integer array value and 0. So, I don't think the segfault was caused by my call to time(0) .. but I'm still not sure what actually happened. Anyways, problem solved. Thanks guys.

A: 

Lovely, but did you intend to pass it a null pointer as time(time_t *t)?

time(NULL);
time(((void*)0));

Not a zero?

xyld
And what do you think NULL expands to?
Nikolai N Fetissov
yes.. it is defined to expand to 0(its true!) but it's still bad coding to use 0 instead of null
Earlz
Actually, recent standards recommend the use of 0 instead of NULL.
Daniel Bingham
@Alcon can you explain that? Link to something explaining that?
xyld
Using `0` in place of `NULL` is evil.
Loadmaster
http://www.lysator.liu.se/c/c-faq/c-1.html
pmg
+3  A: 

Perhaps you have an absurdly large object in your stack frame that's overflowing the stack? See this blog post for a detailed example of how that can occur and an analysis of the situation. The time(2) function allows NULL to be passed to it, and it's highly unlikely your time() implementation has a bug.

Adam Rosenfield
+3  A: 

Often you will find that a segmentation fault will be caught on the incorrect line. What are the lines around it? Is it possible one of those could be causing it?

The standard library's time function take a time_t * as its argument, right? Hence, it's not > surprising you get a segfault: you're trying to dereference a NULL pointer!

time(0) or time(NULL) is the standard and accepted way to access the current time using the time function.

See reference.

Daniel Bingham
Maybe you could drop to assembly and see where this problem really occurs
Earlz
+4  A: 

If you have #include <time.h> the compiler knows that it needs to convert that 0 to a NULL pointer. Otherwise, it passes an int to the function.

I think your implementation treats (int)0 differently than (time_t*)0.

So ... add

#include <time.h>

to your code

Edit

Try this

#include <stdio.h>
#include <time.h>

int main(void) {
    printf("size of (int): %d\n", (int)sizeof (int));
    printf("size of (time_t*): %d\n", (int)sizeof (time_t*));
    return 0;
}
pmg
Unless his C compiler defines `NULL` as `((void*)0)`, in which case the parameter is passed just fine. The return type might be mismatched, though (e.g., `time_t` is `long` instead of `int`).
Loadmaster
`NULL` is a macro. It only gets defined if he `#include <stddef.h>` (or a great many number of other headers). A plain `0` is required to be converted to a NULL pointer, but the compiler will only do that in the presence of a prototype.
pmg
If OP is using a system with 64-bit pointers and 32-bit ints and didn't include `<time.h>`, then `time()` will receive an 8-byte pointer of which only 4 of the bytes are 0 and the other 4 bytes are random stack garbage. `time()` will see this as a non-null pointer, attempt to dereference it, and segfault.
Adam Rosenfield
Except that the first integer/pointer argument is passed in register (`%rdi`, to be specific) on 64-bit OS X systems. The high half would have also been set to zero as a result of the move into the register.
Stephen Canon
@Stephen Canon: Good point, I'd forgotten the x86-64 calling convention passes the first several parameters in registers. This makes the OP's problem more mysterious.
Adam Rosenfield
+1  A: 

Is it possible that your program contains a variable or local function namedtimethat's colliding with the standard library'stimefunction?

Loadmaster
Best guess anyone's put forward yet.
Stephen Canon
wouldn't you get an error on that though? I don't think (strict) C allows you to have a such name collisions
Earlz
@earlz: try it yourself; make one file with the function (say) `int time(int *t) { return *t; }`, and make another file that includes `<time.h>` and calls the standard time function with `time(0)`. Compile with the strictest settings you can and see. Doing this, I am able to compile the code without warning, and it does indeed produce a crash.
Stephen Canon
I suggested it because something similar happened to us (years ago), with a global variable named `link` colliding with the Unix library function `link`.
Loadmaster