gpt4 book ai didi

在C中复制结构体的指针

转载 作者:行者123 更新时间:2023-11-30 14:39:53 26 4
gpt4 key购买 nike

我有以下代码片段:

struct client {
char* ip_address;
int port;
struct timeval last_seen;
};

/* setup socket */

struct client** clients = malloc(0);
unsigned int n_clients = 0;

for (uint32_t iter = 0; ; iter++) {

/* some socket code, that populates client_ip_address, client_prt and timestamp */

n_clients++;
struct client client = {client_ip_address, client_port, timestamp};

clients = realloc(clients, n_clients * sizeof(struct client*));
memcpy(clients[n_clients-1], client, sizeof client);
}

基本上,我试图在数组 clients 内跟踪连接到我的套接字的所有客户端的 IP、端口和时间戳。但是,memcpy 行导致段错误,我做错了什么?

最佳答案

继续评论,没有必要分配指向 struct client的指针,然后为每个struct分配。简单地分配/重新分配一个结构体数组会更有意义。您还必须确保:

/* some socket code populates ip_address, port and timestamp */

实际上为char *ip_address;分配存储空间,因为它只是一个指针,在使用之前必须指向有效的存储空间。

您的分配/重新分配方案也有点不正常。在尝试使用阵列中的附加存储之前,您需要检查是否需要重新分配。此外,您始终realloc到临时指针,以避免丢失指向数据的指针(以及当realloc失败时返回NULL)。如果您使用原始指针重新分配,例如clients = realloc (clients, ...)realloc 返回 NULL 你用 NULL 覆盖你的指针地址您的指针并造成内存泄漏。

打乱顺序并实现临时指针的使用,您可以执行类似以下操作:

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

#define NSTRUCT 8 /* initial number of struct to allocate */

struct client {
char *ip_address; /* must be allocated separately */
int port;
struct timeval last_seen;
};

int main (void) {

size_t n_clients = 0, /* number of clients filled */
n_alloced = NSTRUCT; /* number of clients allocated */
struct client *clients = malloc (n_alloced * sizeof *clients);

if (!clients) { /* validate every allocation */
perror ("malloc-clients");
return 1;
}

for (uint32_t iter = 0; ; iter++) {

if (n_clients == n_alloced) { /* check if realloc required */
/* always realloc with a temporary pointer, or risk data loss */
void *tmp = realloc (clients, 2 * n_alloced * sizeof *clients);
if (!tmp) { /* validate reallocation */
perror ("realloc-clients");
break; /* don't exit, original clients still valid */
}
clients = tmp; /* assign reallocated block to clients */
n_alloced *= 2; /* update allocated number of struct */
}

struct client client = {client_ip_address, client_port, timestamp};
/* some socket code populates ip_address, port and timestamp */
if (/* client filled correctly */) {
memcpy (&clients[n_clients], &client, sizeof client);
n_clients++;
}
}
}

(注意: client.ip_address 的存储必须是已分配类型,此外,由于 client 只是一个结构体, clients[n_clients] = client; 就足够了 - 并且 client 必须完全填充,没有其他成员或子成员需要额外分配的深层复制成员。)

不要忘记在不再需要时free()分配的内存。

编辑 - 某些套接字代码未分配 client.ip_address

由于您的struct client包含一个指向char的指针作为.ip_address成员,如果您的“某些套接字代码” 不会为 .ip_address 分配存储空间,您必须单独复制该成员(深层复制)。使用具有自动存储持续时间的简单成员分配,您可以单独分配并复制 client.ip_addressclients[n_clients].ip_address,如下所示如下:

        /* some socket code populates ip_address, port but doesn't
* allocate storage for client.ip_address -- you must copy.
*/
if (/* client filled correctly */) {
/* assignment is sufficient for non-allocated members */
clients[n_clients] = client;
size_t len = strlen (client.ip_address);
clients[n_clients].ip_address = malloc (len + 1);
if (!clients[n_clients].ip_address) {
perror ("malloc-clients[n_clients].ip_address");
break;
}
memcpy (clients[n_clients].ip_address, client.ip_address,
len + 1);
n_clients++;
}

(这也意味着在释放数组之前,您必须分别 free() 每个 .ip_address 成员)

如果您的编译器提供了 strdup(),您可以将 .ip_address 的副本简化为:

            clients[n_clients].ip_address = strdup (client.ip_address);
/* strdup allocates -- so you must validate */
if (!clients[n_clients].ip_address) {
perror ("strdup-clients[n_clients].ip_address");
break;
}

关于在C中复制结构体的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55860257/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com