我正在尝试给我的程序一个命令行参数,删除第一个字符并将剩余的字符串转换为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);
}
}
答案 0 :(得分:4)
我非常怀疑问题存在,这个
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 摘自解释问题的c11标准。
7.22.4.6
getenv
功能
- 醇>
getenv
函数返回指向与匹配列表成员关联的字符串的指针。指向的字符串不应被程序修改,但可能会被后续调用getenv函数覆盖。如果找不到指定的名称,则返回空指针。
引用来自C11标准草案N1570,我强调了粗体部分,以便明确说明你无法修改指针。