передача целочисленных аргументов при использовании execve

Я начинаю программировать, используя системные вызовы в C. Я пытаюсь использовать вызов execve в одной из моих программ. Мне нужно передать целое число в качестве аргумента в программу, которая вызывается через execve. Однако, читая в Интернете и просматривая пример кода, я вижу, что мы можем передавать только строки в качестве аргументов. Итак, я попытался преобразовать целое число в строку с помощью ‘sprintf’ и затем использовать ‘strcpy’, чтобы скопировать эту строку в один из элементов массива строк, который должен быть передан через execve. Но использование strcpy приводит к ошибке сегментации. Я проверил это путем отладки и если я не использую strcpy, а просто напишу что-то вроде: myargv [1] = «123»; то вся программа работает нормально. Но так как я должен передать переменное целое как параметр, а не константу, я не могу использовать вышеуказанный метод.

Эта проблема уже некоторое время подтачивала меня. Пожалуйста, помогите мне в том, что я должен делать.

    Это почти наверняка, потому что вы не выделили место для своей строки.

    Причина myargv[1]="123"; работает, потому что вы указали указатель на строку, которая уже существует (компилятор обычно помещает «123» в предварительно инициализированную память, и он просто загружается). Используя что-то вроде:

     char *myargv[10]; strcpy (myargv[1], "anything"); 

    вы, как правило, сталкиваетесь с проблемами, поскольку для указателя myargv[1] нет выделенного резервного хранилища.


    Что вы можете сделать, так это просто установить myargv[1] непосредственно в буфер, где вы sprintf -в строке:

     char sprintf_buffer[whatever]; sprintf (sprintf_buffer, "%d", myInteger); myargv[1] = sprintf_buffer; 

    Или, если вы повторно используете этот буфер (чтобы значение было перезаписано для нескольких целых аргументов), используйте strdup .

     char sprintf_buffer[whatever]; sprintf (sprintf_buffer, "%d", myInteger1); myargv[1] = strdup (sprintf_buffer); sprintf (sprintf_buffer, "%d", myInteger2); myargv[2] = strdup (sprintf_buffer); 

    И если по какой-то причине ваша платформа не имеет strdup , вот вам одно:

     char *strdup (const char *s) { char *d = (char *)(malloc (strlen (s) + 1)); if (d != NULL) strcpy (d,s); return d; } 

    Имейте в виду, что вы всегда должны проверять возвращаемое значение strdup чтобы убедиться, что распределение памяти работает. Я оставил его здесь, так как он не имеет отношения к вопросу.


    Вы можете избежать выделения памяти несколькими буферами (если вы знаете абсолютное количество буферов, которые вам понадобятся заранее):

     char sprintf_buffer1[whatever]; char sprintf_buffer2[whatever]; sprintf (sprintf_buffer1, "%d", myInteger1); myargv[1] = sprintf_buffer1; sprintf (sprintf_buffer2, "%d", myInteger2); myargv[2] = sprintf_buffer2; 

    Я не понимаю, почему вы используете strcpy . Просто snprintf число в строку и сделать это одним из аргументов.

    например

     char numberArgBuffer[20]; // more than big enough for a 32 bit integer snprintf(numberArgBuffer, 20, "%d", numberArg); char* argv[3]; char* envp[1]; argv[0] = exeName; // could be same as path argv[1] = numberArgBuffer; argv[2] = NULL; envp[0] = NULL; int ret = execve(path, argv, envp); // if you get here execve failed, so handle the error 

    Ваша strcpy , вероятно, будет сбойной, потому что вы не выделили буфер для адресата, но, как показывает вышеприведенный пример, в любом случае это лишний шаг.