我有一个结构,其中包含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似乎引发了以下警告:“警告:从不兼容的指针类型进行初始化。”
我尝试使用strcpy,但是由于它们不是char []而是char * [],所以似乎不起作用。我有点不知道如何分配它。任何帮助将不胜感激。
答案 0 :(得分:2)
正如@ user3386109所说,这是因为无法分配const express = require('express')
const proxy = require('express-http-proxy');
const http = require('http')
const app = express();
app.use('/admintool', proxy('localhost:2000'));
http.createServer(app).listen(8080, () => console.log('proxy server listening on port 8080!'));
。根据您的情况,从此处有两条路径。如果不打算通过其他代码或通过释放其字符串元素来修改args,那么我们可以像这样将full_command的元素指向它们:
char *full[MAX_ARGS]
但是,如果您需要复制字符串,则必须使用malloc为字符串创建空间,然后使用strcpy复制数据:
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];
}
上述for循环优先:
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]);
}
,因为我们需要空格来容纳空字符最后,如果您需要从args复制字符串,请别忘了遍历并在结束时释放该内存。
str_len + 1
注意:如果需要将要复制的内存清零,则calloc会更好。但是,由于我们使用的是strcpy,因此malloc可以正常工作。
答案 1 :(得分:1)
C语言中的数组对象仅限于两种初始化器:
{}
包围的初始值设定项,即一对{}
,内部具有用于数组元素的单独初始值设定项char []
数组的字符串文字。您的初始化程序不属于这些类别。无效。您不能通过另一个数组初始化一个数组(除了上述情况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);
尽管它可能会因“双重初始化”问题而受苦。
P.S。您尝试执行的操作称为初始化,而不是赋值。在C中分配是完全不同的事情。
答案 2 :(得分:0)
char *args[MAX_ARGS];
args
是MAX_ARGS指针的数组。 args
本身指向第一个指针的内存。 args
保留第一个指针所在的内存地址。 args[0]
是第一个指针的值。 args[0][0]
的意思是,我们转到第一个指针的内存,然后转到该指针指向的内存地址,然后获取该内存地址中第一个字节的值。
char *full_command[MAX_ARGS];
现在,这也是MAX_ARGS指针的数组。 full_command
指向MAX_ARGS * sizeof(char*)
个字节长的内存区域。 full_command[0]
是该内存区域内第一个指针的值。
现在让我们尝试分配:
full_command = args;
现在,我们获得args
中第一个指针的内存地址的值,并将该值分配给full_command
变量。 full_command
的内存已丢失,其他任何句柄都无法再访问它。现在仅args[0] = smth
,并且只有full_command[0] = smth
才有。 full_command
指向args
指向的存储区域。
要复制数组VALUES,您需要复制数组的每个VALUE:
for (size_t i = 0; i < MAX_ARGS; ++i) {
full_command[i] = args[i];
}
或使用memcpy:
memcpy(full_command, args, sizeof(full_command));
这样的操作后,full_command
指向args
的另一个区域,两者的长度均为sizeof(char*) * MAX_ARGS
个字节。它们都具有相同的值。
您需要分配每个数组值:
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));
答案 3 :(得分:0)
您在上面有很多正确答案。简而言之:数组在C语言中很奇怪。您可以初始化它们,但不能分配它们。您不能在结构初始化程序中单独对其进行初始化,但可以将它们作为结构分配的一部分进行分配。
#include <string.h>
int main(int argc, char *argv[])
{
char *test1 [3] = {"a", "b", "c"}; //initialization, not assignment; allowed
char *test2 [3];
//test2 = test1; //assignment of arrays; not allowed
memcpy(test2, test1, sizeof(test1)); //the right way to do a shallow array copy
}
但也令人困惑:
#include <string.h>
struct _array_holder
{
char *array[3];
};
int main(int argc, char *argv[])
{
struct _array_holder test1 = {{"a", "b", "c"}}; //_struct_ initialization; allowed
struct _array_holder test2;
test2 = test1; //assignment of _structs_; allowed!
memcpy(&test2, &test1, sizeof(test1)); //also a fine way to copy a struct
}
因此,不幸的是,没有漂亮的方法(即优雅的语法)来做您想要的事情。这至少是一种合理的独立方式,可以利用结构中的数组分配起作用的事实,从而避免您每次要填充新结构时都必须写几行初始化:
#include <string.h>
#include <unistd.h>
#define MAX_ARGS 5
struct background_element
{
pid_t pid;
int number;
char *full_command[MAX_ARGS];
};
//something akin to a constructor for the struct
struct background_element init_background_element(pid_t pid, int number, char *full_command[])
{
struct background_element ret = {.pid = pid, .number=number};
memcpy(ret.full_command, full_command, sizeof(ret.full_command));
return ret;
}
int main(int argc, char *argv[])
{
pid_t child = 1;
int num_background = 5;
char *args[MAX_ARGS] = {"a", "b"};
//use of the constructor-like thing
struct background_element bg_elem = init_background_element(child, num_background, args);
return bg_elem.pid;
}