使用先前分配的指针调用 strlen 时出现分段错误

segmentation fault while calling strlen with a previously allocated pointer

到目前为止,我有一些代码可以完美地处理名为 wfiles 的变量。 wfiles 在我的主文件中初始化:

char* wfiles = "";

据我所知,C 没有抱怨。接下来在 switch 语句中分配 wfiles 变量:

 switch (c) {
    case 't':
        /* the user wants a template */
        template = optarg;
        break;
    case 'f':
        wfiles = optarg;
        break;
    case 'v':
        vcs = optarg;
        break;
    case 'u':
        url = optarg;
        break;
    case 's':
        /* custom save location */
        save_loc = optarg;
        break;
    case '?':
        break;
    default:
        abort();
    }

最后我检查 wfiles 是否为空:

if (!empty(wfiles))

empty 是一个扩展为 (strlen(wfiles) == 0)

的宏

我看不出有任何问题,但是当我 运行 这段代码时,我遇到了分段错误。这以前从未发生过。当我 运行 gdb 中带有和不带有调试符号的代码时,我得到一行指向前面提到的 if 语句。有谁知道这是为什么?

编辑:

如其他答案中所述,在将指针传递给 strlen() 之前,您确实需要检查 NULL 。在您的情况下,optarg 很可能包含 NULL。因此,最好对 empty() MACRO.

中的传入指针进行 NULL 检查

不过,以下几点仍然有效,所以保持原样。


我认为,您的问题可能与您分配 optargwfiles 的方式有关。 optarg 可能会在不同的迭代中发生变化。所以,只有 指向 optarg 可能会给你错误的结果。您需要为该特定迭代复制 optarg 的内容。

尝试

而不是分配(存储)指针
  • 分配内存给wfiles
  • strcpy() optargwfiles.

或者,您可以直接使用 strdup()

strlen() 将取消引用一个指针,这可能会在该指针(即 optarg 无效时导致一些问题。

例如,在 optarg=NULLc='f' 的情况下,您的代码将执行为:

case 'f':
    wfiles = optarg;
    //Now wfiles=NULL

strlen(wfiles) 将是:strlen(NULL) 并发生分段错误。

更多参考请参阅this related question

您可能希望在调用 strlen() 之前通过 1st 测试其参数是否指向 NULL 来保护宏 empty

#define empty(s) (s) ?(0 == strlen(s)) :1