繁体   English   中英

将 char 数组传递给 const char * 时 strptime 引发分段错误

[英]strptime throws Segmentation fault when passing char array to const char *

当我尝试将 char 数组传递给 const char * 时出现分段错误

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

static char *
get_valid_date_format(const char *date) {
    struct tm result;
    char *ret;
    char **f;
    
    char *formats[] = {"%Y", "%Y-%m", "%y-%m", "%Y-%m-%d", "%y-%m-%d",
        "%Y%m%d", "%y%m%d", "%Y-%m-%d %T", "%y-%m-%d %T", "%Y%m%d%H%M%S",
        "%y%m%d%H%M%S", "%Y-%m-%dT%T", "%y-%m-%dT%T", "%Y-%m-%dT%TZ",
        "%y-%m-%dT%TZ", "%Y-%m-%d %TZ", "%y-%m-%d %TZ", "%Y%m%dT%TZ",
        "%y%m%dT%TZ", "%Y%m%d %TZ", "%y%m%d %TZ", NULL };
        
    
    memset(&result, 0, sizeof(result));
    for (f = formats; f && *f; f++)
    {
        printf("check format: %s\n", *f);
        ret = strptime(date, *f, &result);
        if (ret && *ret == '\0')
        {
            printf("found Format: %s\n\n", *f);
            return *f;
        }
    }

    return (char *)0;
}


void main()
{
    char *format;
    char *date = "2020-07-25T00:10:58";
    char date2[] = "2020-07-25T00:10:58";
    char *date3 = "2020-07-25T00:10:58.000Z";
    
    date2[3] = '1';

    format = get_valid_date_format(date2);
    if (format == NULL) {
        printf("format is NULL\n");
        return;
    } else {
        printf("format found = %s\n", format);
    }
}

如果我调用 get_valid_date_format(date),那么它工作正常。 所以用 char * 调用可以找到,但是当传递 char[] 时,我会遇到分段错误。 我需要使用数组,因为我需要在调用 get_valid_date_format 之前对其进行修改。

正如M. Nejat Aydin 评论的那样, strptime不是标准 C function,它来自 BSD,是 Z6EC1BD1EA6A5D67A63B20C8F14Z 使用的 POSIX 标准的一部分。 为确保已加载,请添加-D_XOPEN_SOURCE=700以加载 X/Open 和 POSIX 扩展。


编译器警告会告诉您许多其他潜在问题。 如果您使用的是 gcc 或 clang 等命令行编译器,则必须运行编译器警告。 有很多选择,我推荐-Wall -Wshadow -Wwrite-strings -Wextra -Wconversion -std=c11 -pedantic

char *formats[]声明 function 本地的char *数组。 您正在返回其中一个元素。 通常返回局部变量会导致 memory 错误,因为 memory 可以在 function 退出时释放。 formats由未释放的字符串文字组成。 但是您错误地将它们声明为可写char * 您可以 go 从非常量到常量,但您不能 go 从常量到非常量

formats应该是const char *formats[] ,一个只读数组const char * 它们是只读字符串文字,永远不会被释放(静态),可以从 function 安全地返回。 对于腰带和吊带,声明formats static因为它只需要分配一次。

同样, get_valid_date_format应该返回static const char *format应该是const char * ,并且f是一个const char **

尽管某些编译器允许void main ,但这是无效的。 main返回一个int

char *foo = "..."; 是不正确的。 它是一个char foo[] = "..."或一个const char *foo如果它是只读的。 这适用于所有日期变量。 const char *date =...const char *date3 = "..."并且因为您修改了date2char date2[] =...

无需检查f在循环中是否为真,只需*f ,但它不会受到伤害。

return (char *)0; 最好写成return NULL;

无需使用memset初始化result ,因为您只是将它传递给strptime ,它将用自己的值覆盖。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM