gpt4 book ai didi

c - 使用 getopt_long() 的段错误

转载 作者:太空宇宙 更新时间:2023-11-04 08:03:02 24 4
gpt4 key购买 nike

对于学校项目,我必须使用 getopt_long() 或 getopt_long_only()。这是我的循环:

while ((get_opt_err = getopt_long(argc, argv, "p:x:y:n:c:f:h",
&help_opt, NULL)) != -1)

我在 valgrind 中报告了这样的段错误:

==2971== Memcheck, a memory error detector
==2971== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==2971== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==2971== Command: ./zappy_server --h
==2971==
==2971== Conditional jump or move depends on uninitialised value(s)
==2971== at 0x4F0B23E: _getopt_internal_r (in /usr/lib/libc-2.25.so)
==2971== by 0x4F0C240: _getopt_internal (in /usr/lib/libc-2.25.so)
==2971== by 0x4F0C2BD: getopt_long (in /usr/lib/libc-2.25.so)
==2971== by 0x400C3D: getopt_server_parsing (getopt_server_parsing.c:42)
==2971== by 0x4008AC: main (main.c:46)
==2971==
==2971== Use of uninitialised value of size 8
==2971== at 0x4C2E8C9: __GI_strncmp (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2971== by 0x4F0B252: _getopt_internal_r (in /usr/lib/libc-2.25.so)
==2971== by 0x4F0C240: _getopt_internal (in /usr/lib/libc-2.25.so)
==2971== by 0x4F0C2BD: getopt_long (in /usr/lib/libc-2.25.so)
==2971== by 0x400C3D: getopt_server_parsing (getopt_server_parsing.c:42)
==2971== by 0x4008AC: main (main.c:46)
==2971==
==2971== Invalid read of size 1
==2971== at 0x4C2E8C9: __GI_strncmp (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2971== by 0x4F0B252: _getopt_internal_r (in /usr/lib/libc-2.25.so)
==2971== by 0x4F0C240: _getopt_internal (in /usr/lib/libc-2.25.so)
==2971== by 0x4F0C2BD: getopt_long (in /usr/lib/libc-2.25.so)
==2971== by 0x400C3D: getopt_server_parsing (getopt_server_parsing.c:42)
==2971== by 0x4008AC: main (main.c:46)
==2971== Address 0x1170 is not stack'd, malloc'd or (recently) free'd
==2971==
==2971==
==2971== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==2971== Access not within mapped region at address 0x1170
==2971== at 0x4C2E8C9: __GI_strncmp (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2971== by 0x4F0B252: _getopt_internal_r (in /usr/lib/libc-2.25.so)
==2971== by 0x4F0C240: _getopt_internal (in /usr/lib/libc-2.25.so)
==2971== by 0x4F0C2BD: getopt_long (in /usr/lib/libc-2.25.so)
==2971== by 0x400C3D: getopt_server_parsing (getopt_server_parsing.c:42)
==2971== by 0x4008AC: main (main.c:46)
==2971== If you believe this happened as a result of a stack
==2971== overflow in your program's main thread (unlikely but
==2971== possible), you can try to increase the size of the
==2971== main thread stack using the --main-stacksize= flag.
==2971== The main thread stack size used in this run was 8388608.
==2971==
==2971== HEAP SUMMARY:
==2971== in use at exit: 29 bytes in 2 blocks
==2971== total heap usage: 2 allocs, 0 frees, 29 bytes allocated
==2971==
==2971== LEAK SUMMARY:
==2971== definitely lost: 0 bytes in 0 blocks
==2971== indirectly lost: 0 bytes in 0 blocks
==2971== possibly lost: 0 bytes in 0 blocks
==2971== still reachable: 29 bytes in 2 blocks
==2971== suppressed: 0 bytes in 0 blocks
==2971== Rerun with --leak-check=full to see details of leaked memory
==2971==
==2971== For counts of detected and suppressed errors, rerun with: -v
==2971== Use --track-origins=yes to see where uninitialised values come from
==2971== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
[1] 2971 segmentation fault (core dumped) valgrind ./zappy_server --h

你知道发生了什么事吗?这是我第一次使用 getopt api,我完全迷路了。这似乎是因为我的 opt 前缀是 -- 但我不知道为什么......

这是我的完整代码:

static void fill_help_opt(struct option *help_opt)
{
help_opt->name = "help";
help_opt->has_arg = 0;
help_opt->flag = NULL;
help_opt->val = 'h';
}

int getopt_server_parsing(int argc, char **argv,
t_server_params *params)
{
int get_opt_err;
t_opts_checkers opts_fcts[7];
int idx;
struct option help_opt;

fill_opts_fcts(opts_fcts);
fill_help_opt(&help_opt);
get_opt_err = 0;
while ((get_opt_err = getopt_long(argc, argv, "p:x:y:n:c:f:h",
&help_opt, NULL)) != -1)
{
idx = 0;
while (idx < 7)
{
if (opts_fcts[idx].key == get_opt_err
&& opts_fcts[idx].value(optarg, params, argv) != 0)
return (1);
++idx;
}
if (get_opt_err == '?')
return (1);
}
return (0);
}

我不想粘贴所有内容,因为我的学校可以找到此代码并指责我作弊......(因为复制/粘贴代码,即使它是我的)。

最佳答案

getopt_long 的第三个参数不应该是单个struct option 的地址,而是指向struct option< 数组第一个元素的指针,最后一个应该用零填充。

因为您没有传入数组,getopt_long 会尝试读取过去的 help_opt,就好像它是一个数组一样。这会调用 undefined behavior .

help_opt 更改为最后一个元素清零的数组。

struct option help_opt[] = {
{ "help", 0, NULL, 'h' },
{ NULL, 0, NULL, 0 }
};

...

while ((get_opt_err = getopt_long(argc, argv, "p:x:y:n:c:f:h",
help_opt, NULL)) != -1)

关于c - 使用 getopt_long() 的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44677433/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com