指向字符指针的指针,或者为什么我不能重新分配这个数组?

时间:2012-02-24 20:42:59

标签: c arrays pointers

我在执行一项非常基本的任务时遇到了很多麻烦:调整数组大小。编程类的每个介绍我曾经教过我这样做,通过创建一个更大的数组,填充它,然后将原始数组指向新的(更大的)数组。

下面的程序将字符串标记为程序名称及其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
}

1 个答案:

答案 0 :(得分:1)

它没有按照你想要的方式行事的原因是因为你按价值传递了args

char ** getArgs( char *input,  char ***args, int ct);

这样,您可以重新分配args

修改:确保在重新分配前释放args。编辑2:那太具体了我。确保您释放所有动态分配的对象。你刚刚离开了很多。

作为旁注,您正在从父进程调用execvp,并从子进程调用wait。它应该是相反的方式。此外,您应该避免将forkexecvp一起使用,而应使用system。你得到的好处是原子操作。