我在执行一项非常基本的任务时遇到了很多麻烦:调整数组大小。编程类的每个介绍我曾经教过我这样做,通过创建一个更大的数组,填充它,然后将原始数组指向新的(更大的)数组。
下面的程序将字符串标记为程序名称及其argv [](它最终将成为基本的shell实现)。它一次为8个参数分配空间 - 如果有超过8个,那么它递归分配一个更大的数组并填充它。
一切都运行良好(请让我知道!)除了我不能将args数组指向moreArgs数组。我有一个声明,应该在getArgs函数的末尾执行此操作,但它不会重新分配args []的地址。我做错了什么?
#define debug 1
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
char ** getArgs( char *input, char **args, int ct);
/*Is there a better way than making these global?*/
char ** args;
char **moreArgs;
int main(int argc, char* argv[]) {
char input[]="echo arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10";
char inputcpy[strlen(input)];
strcpy(inputcpy, input);
char * temp;
temp=strtok(input, " ");
char * prog=temp;
args=( char **) calloc(8, sizeof( char*));
getArgs(inputcpy, args, 1);
if(debug) {
printf("arg address after: %p\n", args);
printf("morearg address after func: %p\n", moreArgs);
}
/*This is basically what the shell will look like. The actual implementation will use stdin
for input. (Unless a pipe or < is present in the input)*/
int q;
int pid=fork();
if (pid!=0) {
execvp(prog, args); //when moreArgs!=null, args should point to moreArgs
return 0;
}
else {
int status=0;
wait(&status);
}
}
/*This function should takes the first argument and inserts int into the second as " " separated tokens. If the second argument is too small -- the function recurses, and resizes the array as needed. The third argument is used to keep
track of the recursion*/
char ** getArgs( char *input, char **args, int ct) {
int adj=(ct-1)*8;//if we recurse, this ensures correct indexes are used
char *inputcpy=malloc(strlen(input));
strcpy(inputcpy, input);
/*Initialize indexes/Prepare for copying*/
int i;
if(ct==1) {
i=1; // this might throw off later adjusts
args[0]=" "; //quick hack to ensure all args are used by exec()
}
else
i=0;
/**Actually do the copying now**/
char *temp=strtok(NULL, " "); //What if later tokens are longer?
args[adj+i++]=temp;
while (temp != NULL && i<8) {
temp=strtok(NULL, " ");
args[adj+i++]=temp;
}
/*If there are more args than we have room for*/
if(i>=8){
//is this allocation right?
moreArgs = (char **) malloc((++ct)*8*sizeof( char *));
/*Fill moreArgs with args*/
int j;
for (j=0; /*j<ct*8 && */args[j]!=NULL; j++) {
moreArgs[j]=args[j];
}
getArgs(inputcpy, moreArgs, (ct) ); //could probably move inc to malloc
//free(args)?
if(ct>1)
args=moreArgs;
}
/*Done with too many args problem*/
return NULL;//(char **) args; //we don't want the global args though
}
答案 0 :(得分:1)
它没有按照你想要的方式行事的原因是因为你按价值传递了args
。
char ** getArgs( char *input, char ***args, int ct);
这样,您可以重新分配args
。
修改:确保在重新分配前释放args
。编辑2:那太具体了我。确保您释放所有动态分配的对象。你刚刚离开了很多。
作为旁注,您正在从父进程调用execvp
,并从子进程调用wait
。它应该是相反的方式。此外,您应该避免将fork
与execvp
一起使用,而应使用system
。你得到的好处是原子操作。