[英]Pointer to a pointer of a character pointer, or why can't I reassign this array?
I'm having a lot of trouble performing a very basic task: resizing an array. 我在执行一个非常基本的任务时遇到很多麻烦:调整数组大小。 Every intro to programming class I've ever taken taught me to do this by creating a larger array, filling it, and then point the original array to the new (larger) one.
我参加过的每次编程班入门课程都教我如何做,方法是创建一个更大的数组,将其填充,然后将原始数组指向新的(更大)数组。
The program below tokenizes a string into a program name and its argv[] (it's ultimately going to be a basic shell implementation). 下面的程序将字符串标记为程序名称及其argv [](最终将成为基本的Shell实现)。 It allocates space for 8 arguments at a time -- if there are more than 8 then it recursively allocates a larger array and fills it.
它一次为8个参数分配空间-如果有8个以上的参数,则它将递归分配一个更大的数组并填充它。
Everything is working well (please let me know otherwise!) except I can't point the args array to the moreArgs array. 一切工作正常(请让我知道否则!),但我无法将args数组指向moreArgs数组。 I have a statement that should do this at the end of the getArgs function but it simply is not reassigning the address of args[].
我有一条语句应该在getArgs函数的末尾执行此操作,但它只是不重新分配args []的地址。 What am I doing wrong?
我究竟做错了什么?
#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
}
The reason it's not behaving the way you want it to is because you're passing args
by value. 它不符合您想要的方式的原因是因为您正在按值传递
args
。
char ** getArgs( char *input, char ***args, int ct);
This way, you can reassign args
. 这样,您可以重新分配
args
。
Edit: Make sure you free args
before reassigning. 编辑:确保在重新分配之前释放
args
。 Edit 2: That was too specific of me. 编辑2:这对我来说太具体了。 Make sure you free all the objects that you dynamically allocated.
确保释放所有动态分配的对象。 There's quite a few that you have just left.
您刚离开了很多地方。
As a side note, you're calling execvp
from the parent process, and calling wait
from the child process. 附带说明一下,您正在从父进程中调用
execvp
,并从子进程中调用wait
。 It should be the other way around. 情况应该相反。 Also, you should avoid using
fork
with execvp
and use system
instead. 另外,您应该避免将
execvp
与fork
一起使用,而应使用system
。 You get the benefit that it's an atomic operation. 您将获得一个原子操作的好处。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.