【问题标题】:My program only works when I declare an extra array我的程序仅在我声明一个额外的数组时才有效
【发布时间】:2019-08-12 23:41:32
【问题描述】:

我正在为一个类构建一个简单的外壳。我的 shell 目录中有两个程序,分别称为“alomundo”和“echo”。 "./alomundo" 打印 "Alo mundo!"到控制台,./echo 使用给定的 args 执行 ubuntu echo。 问题是我的程序只有在我声明 char aux[15] 时才有效。请注意,我不会无缘无故地使用它。有谁能看懂怎么回事?

一个示例输入是

./shell echo a b, alomundo, echo abc

正确的输出是

a b

世界再见!

abc

char aux[15] 没有声明时的输出只是:

世界再见!

abc


#include <stdio.h> 
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    char aux[15]; // <---- GRRRR
    int child; // will hold the childs PID after fork()
    int i = 0; // counter to loop through this mains *argv[]
    int t = 0; // auxiliar counter to loops
    int arg_len; // will hold the length of each argument while the argument is being processed
    int args = 0; // current number of arguments in the argv1 vector
    int send = 0; // boolean to check if the command should be executed in the current loop or not
    char *command; // string to hold the main command name

    char *argv1[15]; // vector to hold the arguments passed to execve

    for(i=1; i<argc; i++) {
        arg_len = strlen(argv[i]);
        argv1[args] = (char *) malloc(sizeof(char) * 25);
        for(t=0; t<25; t++) {
            argv1[args][t] = '\0';
        }

        if (argv[i][arg_len-1] == ',') {
            argv[i][arg_len-1] = '\0';
            send = 1;
        }
        else if (i == (argc-1)) {
            send = 1;
        }

        if (args == 0) {
            command = (char *) malloc(sizeof(char) * 255);
            strcpy(command, "./");
            strcpy(argv1[args], "./");
            strcat(command, argv[i]);
        }
        strcat(argv1[args], argv[i]);
        args++;

        if (send) {
            child = fork();
            if (child == 0) {
                argv1[args+1] = 0;
                execve(command, &argv1[0], envp);
                return 0;
            }
            else {
                waitpid(child);
                free(command);
                for (t=0; t<args; t++) {
                    free(argv1[t]);
                    argv1[t] = NULL;
                }
                args = 0;
                send = 0;
            }
        }
    }
    return 0;
}

【问题讨论】:

  • 您很可能超出了数组的范围。
  • 这绝对是内存损坏的结果。你需要根据你使用的常量仔细检查你的参数长度,比如15。或者,您可以运行 valgrind。但最好的办法是重写您的程序以使用大小检查和大小字符串操作,例如strncpy
  • 代码不能用 gcc 编译,因为envp 没有声明,waitpid() 想要#include &lt;sys/wait.h&gt;,所以不清楚调试你向我们展示的内容是否能解决实际问题.
  • 我用gcc编译的,奇怪。我会在查明是什么后尽快回复你们。谢谢你们的帮助,伙计们!

标签: c shell ubuntu unix gcc


【解决方案1】:
  1. waitpid(child) 似乎错了。尝试:
// ...
#include <sys/wait.h>
// ...
    pid_t child;
    int wstatus;
// ...
            else {
                wait(&wstatus);
  1. envp 未声明。尝试:
// ...
int main(int argc, char *argv[], char *envp[]) {
// ...
  1. argv1 处理中的一个错误。尝试:
// ...
            if (child == 0) {
                argv1[args] = 0;
                execve(command, argv1, envp); // why use &argv1[0] ?
// ...

我认为 (3) 是罪魁祸首。

使用不同级别的优化(-O 等)进行编译似乎会影响错误的+1 是否会导致问题。

【讨论】:

  • 你的意思是“char *envp[]”而不是“*envp[]”吗?
  • 我会尽快测试并给您答复!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-20
相关资源
最近更新 更多