Вопрос

I am assigning one variable to hold the current time:

struct tm *cur = malloc (sizeof (cur));
time_t t = time (NULL);
localtime_r (&t, cur);

I then print the year. It is correct. Next I enter a loop where I assign a new variable time values from a file:

struct stat file_stats;
struct tm *file = malloc (sizeof (file));
lstat (argv[itor], &file_stats);
//check1
localtime_r(&file_stats.st_mtime, file);
//check2

At "check1," cur->tm_year prints a correct and reasonable value. At "check2," cur->tm_year prints "0". What is happening here? I assume it has something to do with me missing something with pointer manipulation. Any help would be greatly appreciated, especially an explanation of what I'm misunderstanding.

Это было полезно?

Решение

I adapted your code into this SSCCE:

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <time.h>

int main(int argc, char **argv)
{
    struct tm *cur = malloc(sizeof(cur));
    time_t t = time (NULL);
    localtime_r(&t, cur);

    printf("curr 1 year: %d\n", cur->tm_year + 1900);

    for (int itor = 1; itor < argc; itor++)
    {
        struct stat file_stats;
        struct tm *file = malloc(sizeof(file));
        file->tm_year = 0;
        if (lstat(argv[itor], &file_stats) == 0)
        {
            printf("curr 2 year: %d\n", cur->tm_year + 1900);
            localtime_r(&file_stats.st_mtime, file);
            printf("curr 3 year: %d\n", cur->tm_year + 1900);
            printf("file 1 year: %d\n", file->tm_year + 1900);
        }
    }
    return(0);
}

The results I got running it were:

curr 1 year: 2013
curr 2 year: 2013
curr 3 year: 2013
file 1 year: 2013
curr 2 year: 2013
curr 3 year: 2013
file 1 year: 2010
curr 2 year: 2013
curr 3 year: 2013
file 1 year: 2013
curr 2 year: 2013
curr 3 year: 2013
file 1 year: 2011

It was useful I had some older files around. Superficially, it looks like there's no problem. However, valgrind had a fit:

==50495== Memcheck, a memory error detector
==50495== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==50495== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==50495== Command: ltr 3d.c const-stuff.c ltr.c madump.c pthread-1.c pthread-2.c pthread-3.c recv.c regress.c send.c strandsort.c x.c
==50495== 
==50495== WARNING: Support on MacOS 10.8 is experimental and mostly broken.
==50495== WARNING: Expect incorrect results, assertions and crashes.
==50495== WARNING: In particular, Memcheck on 32-bit programs will fail to
==50495== WARNING: detect any errors associated with heap-allocated data.
==50495== 
==50495== Invalid write of size 4
==50495==    at 0x105C48: timesub (in /usr/lib/system/libsystem_c.dylib)
==50495==    by 0x1058FE: _st_localsub (in /usr/lib/system/libsystem_c.dylib)
==50495==    by 0x10609D: localtime_r (in /usr/lib/system/libsystem_c.dylib)
==50495==    by 0x100000DE8: main (ltr.c:10)
==50495==  Address 0x10001b188 is 0 bytes after a block of size 8 alloc'd
==50495==    at 0x5686: malloc (vg_replace_malloc.c:274)
==50495==    by 0x100000DC3: main (ltr.c:8)
==50495== 
==50495== Invalid write of size 4
==50495==    at 0x105C70: timesub (in /usr/lib/system/libsystem_c.dylib)
==50495==    by 0x1058FE: _st_localsub (in /usr/lib/system/libsystem_c.dylib)
==50495==    by 0x10609D: localtime_r (in /usr/lib/system/libsystem_c.dylib)
==50495==    by 0x100000DE8: main (ltr.c:10)
==50495==  Address 0x10001b198 is 16 bytes after a block of size 8 alloc'd
==50495==    at 0x5686: malloc (vg_replace_malloc.c:274)
==50495==    by 0x100000DC3: main (ltr.c:8)
==50495== 

And the output went on in a similar vein for quite a while. But it highlights the trouble: you should be using sizeof(*cur) and sizeof(*file) in the malloc() calls. That yields:

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <time.h>

int main(int argc, char **argv)
{
    struct tm *cur = malloc(sizeof(*cur));
    time_t t = time (NULL);
    localtime_r(&t, cur);

    printf("curr 1 year: %d\n", cur->tm_year + 1900);

    for (int itor = 1; itor < argc; itor++)
    {
        struct stat file_stats;
        struct tm *file = malloc(sizeof(*file));
        file->tm_year = 0;
        if (lstat(argv[itor], &file_stats) == 0)
        {
            printf("curr 2 year: %d\n", cur->tm_year + 1900);
            localtime_r(&file_stats.st_mtime, file);
            printf("curr 3 year: %d\n", cur->tm_year + 1900);
            printf("file 1 year: %d\n", file->tm_year + 1900);
        }
    }
    return(0);
}

And valgrind gives that a clean bill of health.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top