【问题标题】:c99 problems with pointers and localtime_rc99 指针和 localtime_r 的问题
【发布时间】:2013-02-26 05:48:22
【问题描述】:

我正在分配一个变量来保存当前时间:

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

然后我打印年份。它是正确的。接下来我进入一个循环,从文件中分配一个新的变量时间值:

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

在“check1”处,cur->tm_year 打印出正确且合理的值。在“check2”处,cur->tm_year 打印“0”。这里发生了什么?我认为这与我缺少指针操作有关。任何帮助将不胜感激,尤其是对我的误解的解释。

【问题讨论】:

  • 虽然没关系,但为什么要动态分配呢?为什么不分配一个struct tm 并将其地址传递给localtime_r()
  • 不知道为什么我选择使用动态分配,但我认为这确实很重要,因为在将它们更改为 struct tm 之后,事情似乎正在发挥作用。谢谢,我猜,但知道为什么会这样吗?
  • 是的:您应该在malloc() 调用中使用sizeof(*cur)sizeof(*file)。我只是在写一个答案,并意识到这就是问题所在(感谢valgrind)。

标签: pointers c99 localtime time.h


【解决方案1】:

我将您的代码改编成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);
}

我运行它的结果是:

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

我有一些旧文件很有用。从表面上看,似乎没有问题。但是,valgrind 很适合:

==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== 

输出以类似的方式持续了很长一段时间。但它突出了问题:您应该在malloc() 调用中使用sizeof(*cur)sizeof(*file)。这会产生:

#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);
}

valgrind 提供了一份干净的健康证明。

【讨论】:

  • 哦,这很有道理。那么malloc(sizeof(*cur)) 会分配cur 指向的结构所需的空间量吗?和以前一样,使用malloc(sizeof(cur)) 我只是分配指针所需的空间量。我的理解正确吗?
猜你喜欢
  • 1970-01-01
  • 2020-12-06
  • 1970-01-01
  • 2011-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多