提问者:小点点

为char*[]结构数据元素赋值会给出警告


我有一个包含char*]类型值的结构。它的定义是这样的:

struct background_element
{
    pid_t pid;
    int number;
    char *full_command[MAX_ARGS];
};

我还有一个全局char*[]变量args。

char *args[MAX_ARGS];

我尝试创建一个struct background_element类型的新变量,并按如下方式分配full_command值:

struct background_element bg_elem = { .pid = child, .number = num_background, .full_command = args};

但是,将args赋给.full_command似乎会抛出此警告:“Warning:initialization from incompatible pointer Type.”

我试过使用strcpy,但是因为它们不是char[]而是char*],所以似乎不起作用。我有点不知道怎么分配这个。如有任何帮助,我们将不胜感激。


共3个答案

匿名用户

正如@user3386109所说的,这是因为无法分配给。从这里开始有两条路,这取决于你的情况。如果args不会被修改,不管是通过其他代码还是通过释放它的字符串元素,那么我们可以将full_command的元素指向它们,如下所示:

struct background_element bg_elem = {.pid = child, .number = num_background};
for (unsigned int i = 0; i < MAX_ARGS; i++) {
    bg_elem.full_command[i] = args[i];
}

但是,如果需要复制字符串,则必须使用malloc为字符串创建空间,然后使用strcpy将数据复制到:

for (unsigned int i = 0; i < MAX_ARGS; i++) {
    int str_len = strlen(args[i]);
    bg_elem.full_command[i] = malloc((str_len + 1) * sizeof(char));
    strcpy(bg_elem.full_command[i], args[i]);
}

以上为循环优先:

    ,因为我们需要空字符/li>的空间

最后,如果需要从arg中复制字符串,不要忘记遍历并在完成后释放内存。

for (unsigned int i = 0; i < MAX_ARGS; i++) {
    free(bg_elem.full_command[i]);
}

注意:如果您需要将正在复制的内存归零,那么calloc会更好。然而,由于我们使用的是strcpy,malloc工作得很好。

匿名用户

C语言中的数组对象仅限于两种初始值设定项:

    ,其中包含数组元素的单独初始值设定项/li> 数组的字符串文本。/li>

您的初始值设定项不属于这些类别中的任何一个。它是无效的。您不能用另一个数组初始化一个数组(除了上面的情况2)。

在形式上,您可以显式地将其拼写出来

struct background_element bg_elem = 
{ 
  .pid = child, 
  .number = num_background, 
  .full_command = { args[0], args[1], /* ... and so on */ }
};

但这并不是一个真正可行的方法。一个更好的主意是

struct background_element bg_elem = 
{ 
  .pid = child, 
  .number = num_background
};

static_assert(sizeof bg_elem.full_command == sizeof args, "");
memcpy(bg_elem.full_command, args, sizeof args);

尽管它可能会受到“双重初始化”问题的影响。

附注。你试图做的事情叫做初始化,而不是赋值。赋值在C中是一个非常不同的东西。

匿名用户

char *args[MAX_ARGS];

是MAX_ARGS指针数组。本身指向第一个指针的内存。保存第一个指针所在的内存地址。是第一个指针的值。的意思是,我们转到第一个指针的内存,然后转到该指针指向的内存地址,然后得到该内存地址中第一个字节的值。

char *full_command[MAX_ARGS];

现在,这也是一个MAX_ARGS指针数组。指向长度为字节的内存区域。是该内存区域内第一个指针的值。br>现在让我们尝试赋值:

full_command = args;

现在我们得到中第一个指针的内存地址的值,并将该值赋值到变量中。的内存丢失,任何其他句柄都无法访问它。现在仅当指向指向的内存区域。br>要复制数组值,需要复制数组的每个值:

for (size_t i = 0; i < MAX_ARGS; ++i) { 
     full_command[i] = args[i];
}

或使用memcpy:

memcpy(full_command, args, sizeof(full_command));

在这样的操作之后,指向与不同的区域,两者都是字节长。并且它们都具有相同的值。br>您需要为每个数组赋值:

struct background_element bg_elem = {
   .pid = child, 
   .number = num_background, 
   .full_command = { args[0], args[1], args[2], ....<up until MAX_ARGS> }, 
};

这不太有用,每次MAX_ARGS改变时都需要修改它。因此使用memcpy或循环:

struct background_element bg_elem = {
    .pid = child, 
    .number = num_background, 
};
memcpy(bg_elem.full_command, args, sizeof(bg_elem.full_command));