如何更改另一个函数中的字符串指针数组?

时间:2018-04-30 07:06:44

标签: c arrays pointers

我一直在试图弄清楚如何修改一个char指针数组,但无论我做什么,似乎都没有变化下面是我试图改变的三个数组,包括调用函数我是使用

char*cm1[5];
char*cm2[5];
char*cm3[5];
setupCommands(&cm1,commands,file,0);
setupCommands(&cm2,commands,file,1);
setupCommands(&cm3,commands,file,2);

下面的代码是函数本身。我在想它可能涉及双指针,但如果我尝试使用* cmd更改数组,我会遇到分段错误。

void setupCommands(char **cmd[], char* commands[],char file[],int index){



    char str1[255];
    strcpy(str1,commands[index]);
    char newString [5][255];
    int j = 0;
    int ctr = 0;
    int i;
    //printf("str1 %s\n" ,str1);

    for(i = 0; i <= strlen(str1); i++){

        if(str1[i] == ' '|| str1[i] =='\0'){
            newString[ctr][j] = '\0';
            ctr++;//next row
            j=0;// for next word, init index to 0
        }else{
            newString[ctr][j]=str1[i];
            j++;
        }
    }


    for(i = 0; i < ctr; i++){
            //printf(" test2 %s \n", newString[i]);
        cmd[i] = newString[i];
            //printf(" test2 %d %s \n", i,cmd[i]);
    }
 //printf("index %d", i);
  cmd[i]= file;
  cmd[i + 1] = NULL;

  //execvp(cmd[0],cmd);
   //cmd
}

2 个答案:

答案 0 :(得分:2)

首先 - 作为三星指针程序员并不好:)

您可以使用指向本地变量的指针进行分配,该变量在函数返回后不再可用

但如果你还想要三颗星指示:

char **cm1;
char **cm2;
char **cm3;
setupCommands(&cm1,commands,file,0);
setupCommands(&cm2,commands,file,1);
setupCommands(&cm3,commands,file,2);
#define MAXWORD 256

int setupCommands(char ***cmd, const char *commands,const char *file,int index){

    char str1[255];
    strcpy(str1,commands[index]);

    int j = 0;
    int ctr = 0;
    int i;
    //printf("str1 %s\n" ,str1);

    *cmd = malloc(sizeof(char *));
    **cmd = malloc(MAXWORD);
    if(!*cmd || !**cmd) 
    {
        /* do spmething if mallocs failed*/
        return -1;
    }
    for(i = 0; i <= strlen(str1); i++){

        if(str1[i] == ' '|| str1[i] =='\0'){
            (*cmd)[ctr][j] = '\0';
            ctr++;//next row
            *cmd = realloc((ctr + 1) * sizeof(int));
            (*cmd)[ctr] = malloc(MAXWORD);
            if(!*cmd || !*cmd[ctr]) 
            {
            /* do spmething if mallocs failed*/
                return -1;
            }

            j=0;// for next word, init index to 0
        }else{
            (*cmd)[ctr][j]=str1[i];
            j++;
        }
    }


    *cmd = realloc(sizeof(char *)  * ctr + 2)  
    (*cmd)[ctr - 2] = malloc(MAX);
    if(!*cmd || !*cmd[ctr - 2]) 
    {
        /* do spmething if mallocs failed*/
        return -1;
    }
    strcpy((*cmd)[ctr - 2], file);
    (*cmd)[ctr - 1] = NULL;

    return 0;

  //execvp(cmd[0],cmd);
   //cmd
}

你可以改进很多东西(例如,不是每次都重新分配,而是在更大的块中)并且我没有改变你的代码逻辑中的任何东西。

答案 1 :(得分:2)

  1. 您的代码存在一些问题:
    • 当函数退出时,你试图返回对本地'char newString [5] [255]'的引用。在简单的世界中 - 永远不会返回堆栈上本地分配的任何内容。这就是您获得分段错误的原因。
    • 必须声明
    • char **cmd[] char *cmd[] - 即使您会收到编译器assignment from incompatible pointer type的警告,代码也会正确运行并执行(基本上** cmd []会执行与* cmd []相同的工作,即使它没有正确的类型)如果你没有返回对本地对象的引用;
  2. 简单而简单的优化只是删除数组str1并直接对数组commands进行操作。

    除了这个简单的优化之外,我已经改变了你的代码以克服分段错误,通过在堆上分配,而不是堆栈(将一直存在直到程序终止)多维数组,我也计算它的大小所以我会知道分配多少内存。现在可以安全地返回对它的引用。

    请注意,可以进行更多优化,但为了简单起见,这是此代码工作的最小限度。

    int setupCommands(char *cmd[], char *commands[], char file[], int index)
    {
    int j = 0;
    int ctr = 0;
    int i = 0;
    
    int rows = 0;
    int cols = 0;
    
    char **newString = NULL;
    
    while(commands[index][i])
    {
        if (commands[index][i] == ' ')
        {
            ++rows;
        }
    
        ++i;
    }
    ++rows;
    
    cols = strlen(commands[index]) + 1;
    
    newString = malloc(rows * sizeof(*newString));
    if (newString == NULL)
    {
        return -1;
    }
    
    for (i = 0; i < rows; ++i)
    {
        newString[i] = malloc(cols * sizeof(*newString));
        if (newString[i] == NULL)
        {
            return -1;
        }
    }
    
    for(i = 0; i <= strlen(commands[index]); i++){
    
        if(commands[index][i] == ' '|| commands[index][i] =='\0'){
            newString[ctr][j] = '\0';
            ctr++;//next row
            j=0;// for next word, init index to 0
        }else{
            newString[ctr][j]=commands[index][i];
            j++;
        }
    }
    
    for(i = 0; i < ctr; i++){
    
        cmd[i] = newString[i];
    
    }
    
    cmd[i]= file;
    cmd[i + 1] = NULL;
    
    return 0;
    }