我试图给我的程序一个命令行参数,去掉第一个字符并将剩余的字符串转换为 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摘自 c11解释问题的标准。
7.22.4.6 The
getenv
function
- 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/