c中的动态char **数组

时间:2013-04-06 17:19:53

标签: c pointers memory-management

我正在尝试执行execv()命令,第二个参数是要传递的参数列表。

我的论据目前以字符串格式保存,即

--config=moo --console --something=moo2 --path="this can have spaces" --format=x

我想做的是把它分成char**个参数,即

argv[0] = "--config=moo"
argv[1] = "--console"

我不太了解的是一件事(道歉,自从我上次使用C以来已经很长时间了)。如果我想构建一个字符串以放入这个argv数组,我该怎么做,例如: -

char* argv[10];
char* myPath = getMyPath();
argv[0] = "--config=moo";
argv[1] = ... ... ... 
...
...
argv[10] = "--path=" + myPath;

我相信在C中不允许这样做,因为我必须事先分配所有内存,所以通过将argv分配为10个元素,我不能再单独定义每个内存..或者我可以吗?

我知道+修饰符在C中不起作用,但是我不确定我需要复制它的函数(我意识到我可以使用strcat添加到现有的已定义数组,但是我不认为这会使用新形成的数组)

4 个答案:

答案 0 :(得分:1)

你可以malloc strcat()将使用的内存,或者你可以在堆栈上使用大于需要的char buffer[N]

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


const char * someFunction();

int main(int argc, char ** argv) {

  const char[] path = "commandName";
  const char[] arg1 = "--config=moo";
  const char[] arg2 = "--console";
  const char[] arg3 = "--something=moo2";
  //arg4 is skiiped
  const char[] arg5 = "--format=x";

  const char * mypath = someFunction();
  const char[] pathprefix = "--path=";

  size_t pathprefixlength = strlen(pathprefix);
  size_t stringlength =  pathprefixlength + strlen(mypath);

  char * arg4 = (char *)malloc(stringlength + 1);

  strcpy(arg4, pathprefix);
  strcpy(arg4 +  pathprefixlength, mypath);

  arg4[stringlength] = '\0'; //null terminate
  char *argvec[7]; // array of pointers
  argvec[0] = path;
  argvec[1] = arg1;
  argvec[2] = arg2;
  argvec[3] = arg3;
  argvec[4] = arg4;
  argvec[5] = arg;
  argvec[6] = NULL;
  //do something with argvec;
  free(arg4);
}

答案 1 :(得分:1)

General malloc

man malloc可能会有所帮助。 malloc获取内存所需的minimum个字节数(即malloc可以选择为您提供更多内容)。因此,如果您的10数组中只需要char个元素,那么最好只是按照您已经完成的方式分配char* argv[10]。但是,这会为10 char*创建一个尚未定义的容器。因此,对于每个char*argv[0]...argv[9],您可以准确定义其中的内容。例如,如果你想为argv[0] malloc一个大小为200的字符串,你可以使用如下语句(注意200可以保存在常量或变量中):

argv[0] = malloc(200 * sizeof(char));

通常,sizeof(char) == 1 byte,所以这个值可能会尝试获得200个字节。但是,此时您可以以任何方式修改argv[0](例如strncpystrncat等。)

现在,如果你不知道你可能有多少个参数,你可以动态分配你的容器。因此,您可以尝试分配char* argv[10]而不是char** argv。为此,您将执行以下语句:

int SOME_SIZE = 1500 ; // Or some dynamic value read, etc.
char** argv = malloc(SOME_SIZE * sizeof(char*));

通常是32位系统上的sizeof(char*) == 4 bytes(典型指针的大小)。现在,您可以使用此块内存argv,方式与以前类似。为了便于思考,以这种方式使用malloc允许您执行char* argv[WITH_SOME_DYNAMIC_NUMBER]的相对等效操作。因此,您可以像我上面描述的那样操作这个新容器。

请记住,当您完成malloc创建的内存时,必须调用free,否则在程序终止之前不会取消分配。

您的问题

如果我理解你的问题,你有一个扁平的字符串,你想把它变成execve的字符串数组。我将找出一个简单的例子,试图解释一下这可以做的很多方法之一。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void someMethod()
{
  char* argv[10];
  char* path = getMyPath();

  // Notice - this is a little messy and can/should be encapsulated away in another
  // method for ease of use - this is to explicitly show, however, how this can work.
  argv[9] = malloc((strlen(path) + strlen("--path=") + 1) * sizeof(char));
  strncpy(argv[9], "--path=", strlen("--path="));
  argv[9][strlen("--path=")] = '\0'; // NULL-terminate since strncpy doesn't
  strncat(argv[9], path, strlen(path));

  // Do stuff with array
  printf("%s\n", argv[9]);

  // Technically, you should never get here if execve succeeds since it will blow this
  // entire program away (unless you are fork()'ing first)
  free(argv[9]);
}

答案 2 :(得分:0)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* strcata(char* s1, char* s2){
    char *p;
    p=(char*)malloc(sizeof(char)*(strlen(s1)+strlen(s2)+1));
    if(p == NULL) return NULL;

    *p='\0';

    return strcat(strcat(p, s1), s2);
}

int main(int argc, char *argv[])
{
    char *p;

    p=strcata("--path=", ".:./bin");
    printf("%s\n", p);

   return 0;
}

答案 3 :(得分:0)

您可以使用malloc进行动态内存分配

例如,假设我们有以下简单结构:

struct myRecord {

 char firstName[60];

 char lastName[60];

 int employeeID;

 struct myRecord * nextRecord;

};

struct myRecord * headPtr; // point to first structure in the list
// This line allocates memory for the first record:
headPtr = (struct myRecord *)malloc(sizeof(myRecord));