Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C-如何将struct元素添加到动态分配的结构数组中?_C_Arrays_Dynamic_Struct_Realloc - Fatal编程技术网

C-如何将struct元素添加到动态分配的结构数组中?

C-如何将struct元素添加到动态分配的结构数组中?,c,arrays,dynamic,struct,realloc,C,Arrays,Dynamic,Struct,Realloc,正在尝试向C中的结构数组添加另一个元素(特定于Windows,使用VS2019社区)。工作正常,直到我尝试将realloc的返回值分配给原始数组。main中的代码(声明和初始化,以及调用代码)如下所示: // server.h struct server { wchar_t* name; wchar_t ip_address[16]; int port; }; // main.c static int nb_servers = 0; static struct serv

正在尝试向C中的结构数组添加另一个元素(特定于Windows,使用VS2019社区)。工作正常,直到我尝试将realloc的返回值分配给原始数组。main中的代码(声明和初始化,以及调用代码)如下所示:

// server.h
struct server {
    wchar_t* name;
    wchar_t ip_address[16];
    int port;
};

// main.c
static int nb_servers = 0;
static struct server* servers = NULL;

void add_server(wchar_t* name, wchar_t ip_address[16], wchar_t* port)
{
    struct server newserver;
    newserver.name = name;

    wcsncpy(newserver.ip_address, ip_address, 16);

    char* port_char = malloc(6);
    if (port_char == NULL) {
        exit(EXIT_FAILURE);
    }
    size_t i;
    wcstombs_s(&i, port_char, 6, port, _TRUNCATE);

    int port_int = 0;
    str2int(&port_int, port_char, 10);

    newserver.port = port_int;

    // add to servers
    nb_servers = server_add(&servers, &newserver, nb_servers);
}
然后在另一个文件中,我尝试将新服务器添加到列表中:

// server.c
int server_add(struct server** servers, struct server* myserver, int nb_servers)
{
    struct server* tmp = (struct server*) realloc(*servers, (nb_servers + 1) * sizeof(struct server));
    if (tmp == NULL) {
        exit(EXIT_FAILURE);
    }

    tmp[nb_servers].name = (wchar_t*) calloc(strlen(myserver->name), sizeof(wchar_t));
    if (tmp[nb_servers].name == NULL) {
        exit(EXIT_FAILURE);
    }
    wcsncpy(tmp[nb_servers].name, myserver->name, strlen(myserver->name));
    wcsncpy(tmp[nb_servers].ip_address, myserver->ip_address, 16);
    tmp[nb_servers].port = myserver->port;

    *servers = tmp; // this only copies the first value [0]
                    // also tried **servers = *tmp and other combinations, nothing seems to work.

    return ++nb_servers;
}
但只有第一个值被“复制”,或者说只有服务器[0]指向有效对象。但是,tmp[0]到tmp[nb_服务器-1]是有效的,并且包含正确的数据。我在remove_server方法中使用了一种类似的重新分配机制来收缩阵列,在这种情况下,同样的重新分配也会起作用

问题
如何通过动态重新分配内存将结构项正确添加到结构数组中?

首先,您了解真正的作用是什么吗(特别是当要复制的数据长度达到或超过目标缓冲区提供的长度时?不相关,我想我是@WhozCraig,参考中的解释很清楚。我应该复制len-1个字符,并用null终止字符串吗?(你可以猜到我完全是C语言的初学者)。您应该设置动态分配以包含终止符的空间,然后只使用
wcscpy
或..如果您的实现支持它,只使用
wcsdup
(这两个步骤都为您完成)。@WhozCraig我现在这样做:
wcsncpy(tmp[nb_服务器]。name,myserver->name,wcslen(myserver->name)-1);tmp[nb_服务器]。name[wcslen(myserver->name)]='\0';
我还删除了alloc方法中的返回值强制转换。这是可行的,但最初的问题仍然存在:服务器只包含tmp的第一个元素。这仍然是错误的。按照我们说的做。为名称分配长度+1,只需使用
wcscpy
。就像现在的情况一样,您是(a)在“复制字符串”下,以及(b)通过访问超过分配长度的内存一个字符来调用未定义的行为。假设您能够正确地执行此操作,那么您实际如何验证添加操作失败?该代码未发布。