在 C 中动态创建 Char* 数组

Create Char* array dynamically in C

我正在尝试为 execv 动态创建一个 char* 数组。参数的数量只有在运行时才知道。 这是我的代码:

char *id_array= malloc((size_array) * sizeof(char));
int length = 4 + groupId_list.nr; //groupId_list.nr know only at runtime
id_array= realloc(id_array,sizeof(char)*length);

id_array[0] = "/usr/bin/java";
id_array[1] = "-jar";
id_array[2] = "pathToFile/jar";

for (int j = 0; j < groupId_list.nr; j++) {
    id_array[j+3] = groupId_list.items[j].string;
}
id_array[size_array-1] = (char*)0; //terminator need for execv

execv("/usr/bin/java",&id_array);

当我编译代码时,我有不同的警告:

warning: incompatible pointer to integer conversion assigning to 'char' from 'char [14]'
 id_array[0] = "/usr/bin/java";
warning: incompatible pointer to integer conversion assigning to 'char' from 'char [5]'
 id_array[1] = "-jar";
....

我尝试按照不同的教程进行操作,但我不明白如何解决它。 谢谢

您正在尝试将 char * 存储在 char 中,您必须使用指针指针:

char **id_array = malloc((size_array) * sizeof(char *));

字符串文字是 const char[]const char * 的静态等价物)。

您需要一个字符串数组、一个字符数组、一个指向字符的指针。

int length = 4 + groupId_list.nr;
char **id_array= malloc(sizeof(char*) * length);

const char *str1 = "/usr/bin/java";
id_array[0] =  malloc(sizeof(char) * (strlen(str1) + 1));
strcpy(id_array[0], str1);

const char *str2 = "-jar";
id_array[1] =  malloc(sizeof(char) * (strlen(str2) + 1));
strcpy(id_array[1], str2);

const char *str3 = "pathToFile/jar";
id_array[2] =  malloc(sizeof(char) * (strlen(str3) + 1));
strcpy(id_array[2], str3);

for (size_t j = 0; j < groupId_list.nr; ++j) {
    id_array[j + 3] = malloc(sizeof(char) * (strlen(groupId_list.items[j].string) + 1));
    strcpy(id_array[j + 3], groupId_list.items[j].string);
}

id_array[length - 1] = NULL;

当您使用 sizeof(*variable) 时,它会变得更清晰,这样更易​​读,更不容易出错,也更清晰。此外,只需调用 strdup.

即可简化 const char *string = "some string"; malloc(strlen(string) + 1); strcpy 部分
char **id_array= malloc(sizeof(*id_array) * 4);
id_array[0] = strdup("/usr/bin/java");
id_array[1] = strdup("-jar");
id_array[2] = strdup("pathToFile/jar");
for (int j = 0; j < groupId_list.nr; j++) {
    id_array[j + 3] = strdup(groupId_list.items[j].string);
}
id_array[length - 1] = NULL;

记得释放内存。

或者根据您的内存所有权模型,您可能不想复制内存而只是分配指针。然后只需为指向 char 的指针数组分配内存并分配指针。您可以为堆栈上的字符串文字分配内存。

char **id_array = malloc(sizeof(*id_array) * length);
id_array[0] = (char[]){"/usr/bin/java"};
id_array[1] = (char[]){"-jar"};
id_array[2] = (char[]){"pathToFile/jar"};
for (....) { 
   id_array[j + 3] = groupId_list.items[j].string;
}
id_array[length - 1] = NULL;

或者您甚至可以仔细阅读 execv specification (see this post) 并将指向字符串文字的指针传递给 execv 并忽略 const 限定符,因为 execv 不会修改数组无论如何。

# string literals are constant
const char **id_array = malloc(sizeof(*id_array) * length);
id_array[0] = "/usr/bin/java";
id_array[1] = "-jar";
id_array[2] = "pathToFile/jar";
for (....) { 
   id_array[j + 3] = groupId_list.items[j].string;
}
id_array[length - 1] = NULL;

# explicitly remove the const qualifier, which is safe, because we 
# know from the documentation that execv will not modify the array contents
execv(...., (void*)id_array);