c - 测试字符串中的第一个字符给出段错误

标签 c

我试图给我的程序一个命令行参数,去掉第一个字符并将剩余的字符串转换为 int。但当我使用 if (argv[i][0] == 'w') 进行测试时,出现段错误。

$ ./program w10
Segmentation fault

 

#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <argp.h>
#include <python2.7/Python.h>


/* If this flag is nonzero, don’t handle the signal right away. */
volatile sig_atomic_t signal_pending;

/* This is nonzero if a signal arrived and was not handled. */
volatile sig_atomic_t defer_signal;

void
huphandler (int signum)
{
  if (defer_signal)
    signal_pending = signum;
  else
    exit(0);
}


int
main(int argc, char **argv)
{
        signal(SIGHUP, huphandler);

        int i;
        int wait = 0;
        char *args[argc+3];
        args[0] = "mypy.py";
        for (i=0; i<argc; i++) {
                if (argv[i][0] == 'w') { // Here's where the problem is
                        memmove(argv[i], argv[i]+1, strlen(argv[i]));
                        wait = strtol(argv[i], NULL, 10);
                }
                else {
                        args[i+1] = argv[i];
                        printf("%s\n", args[i+1]);
                }
        }
        argc = i + 2;
        FILE *file;
        Py_SetProgramName(args[0]);
        Py_Initialize();
        PySys_SetArgv(argc, args);

        while (true) {
                defer_signal++;
                file = fopen(strcat(getenv("HOME"), "/mypy.py"), "r");
                PyRun_SimpleFile(file, "mypy.py");
                Py_Finalize();
                defer_signal--;
                if (defer_signal == 0 && signal_pending != 0)
                        exit(0);
                if (wait > 0) sleep(wait);
                else exit(0);
        }
}

最佳答案

我非常怀疑问题就在那里,这个

fopen(strcat(getenv("HOME"), "/mypy.py"), "r");

另一方面,这是非常非常错误的。

标准禁止修改 getenv() 返回的指针1,相反,您应该使用临时缓冲区,这应该可以做到

FILE *file;
char path[PATH_MAX]; // Include <limits.h>
int result;
const char *home;
home = getenv("HOME");
if (home == NULL)
    return EXIT_FAILURE; // Problem, `HOME' env variable not found?
result = snprintf(path, sizeof(path), "%s/mypy.py", home);
if ((result < 0) || (result >= (ssize_t) sizeof(path))
    return EXIT_FAILURE' // Very unlikely to happen, BUT CHECK PLEASE.
file = fopen(path, "r")
if (file == NULL) // Please always check ...
    return EXIT_FAILURE;

这可能会导致未定义的行为,这意味着您不能期望给定的行为,因此您不能期望程序的其余部分正常工作。


1摘自 解释问题的标准

7.22.4.6 The getenv function

  1. The getenv function returns a pointer to a string associated with the matched list member. The string pointed to shall not be modified by the program, but may be overwritten by a subsequent call to the getenv function. If the specified name cannot be found, a null pointer is returned.

引用自C11标准草案N1570,我突出显示了粗体部分,以便清楚地表明不能修改指针。

关于c - 测试字符串中的第一个字符给出段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35134574/

相关文章:

c - 我不知道为什么代码中的输入会被回退。 C语言

c - 如何在 C 中初始化一个相当复杂的 char 数组?

c - C 中的结构数组参数

c - 将文件内容或字符串拆分为相同大小的字符串数组

python - 有没有办法直接在 python (或 Ironpython)中导入 c *.lib 而不进行任何包装?

c - 全局变量未正确递增

c - 奇怪的 for 循环条件

c - C中的链表程序挂了

C 变量定义

c - 如何使用 LLIST *mylist[N];