首页 > 解决方案 > 在 C 中为缓冲区(结构类型)分配内存

问题描述

我正在编写一个具有以下结构的 C 程序:

struct packet_info{
    char *ip_src;
    char *ip_dst; 
    u_short th_sport;
    u_short th_dport; 
    u_int   th_seq;
};

struct key_value{
    struct packet_info key;
    long unsigned int value;
};

我想创建一个key_value包含 1000 个项目(MAX_SIZE)的缓冲区。但是,我不知道如何为它分配内存。

我是这样做的:

struct key_value *buffer = malloc(MAX_SIZE * sizeof(struct key_value))

但是,在阅读了以下问题/答案 - malloc for struct and pointer in C - 我得出的结论是,我还需要为char* ip_srcand分配空间char* ip_dst

毕竟,为缓冲区分配内存的正确方法是什么?

标签: c

解决方案


假设你想要堆上的所有东西,我会做这样的事情:

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

#define MAX_SIZE 1000

typedef struct packet_info{
    char *ip_src;
    char *ip_dst; 
    unsigned short th_sport;
    unsigned short th_dport; 
    unsigned int   th_seq;
} packet_info;

typedef struct key_value{
    packet_info key;
    long unsigned int value;
} key_value;

int main() {
    key_value *buffer = malloc(MAX_SIZE * sizeof(key_value));
    for(int i=0; i<MAX_SIZE; i++) {
        buffer[i].key.ip_src = calloc(16, sizeof(char)); // space for `###.###.###.###\0`
        buffer[i].key.ip_dst = calloc(16, sizeof(char));
    }

    //... do stuff ...
    buffer[0].value = 10;
    buffer[0].key.th_sport = 69;
    buffer[0].key.th_dport = 420;
    strcpy(buffer[0].key.ip_src, "127.0.0.1");
    strcpy(buffer[0].key.ip_dst, "8.8.8.8");
    // ...

    // now cleanup
    for(int i=0; i<MAX_SIZE; i++) {
        free(buffer[i].key.ip_src);
        free(buffer[i].key.ip_dst);
    }
    free(buffer);
    buffer = NULL;
}

使用循环来分配和清零内存块。请记住释放您分配的所有内容,并且*buffer只有在您完成使用它来释放 IP 之后才能释放!

跟踪分配了每个结构的数量以及realloc()必要时可能很有用。您可能还想考虑如何访问数据并将其存储为链表或数组或指针数组(等)。


我编译这个例子

gcc -g -std=c11 -c main.c
gcc main.o -o main.exe

然后开始调试gdb main.exe

(gdb) b 36
Breakpoint 1 at 0x401632: file main.c, line 37.
(gdb) r
Starting program: C:\Users\Pedro\Desktop\t\main.exe

Breakpoint 1, main () at main.c:37
37              for(int i=0; i<MAX_SIZE; i++) {
(gdb) p buffer
$1 = (key_value *) 0x5044d0
(gdb) p buffer[0]
$2 = {key = {ip_src = 0x5020d0 "127.0.0.1", ip_dst = 0x502110 "8.8.8.8", 
             th_sport = 69, th_dport = 420, th_seq = 3131961357}, value = 10}
(gdb) p buffer[0].key.th_seq
$3 = 3131961357

@OznOg 想知道我为什么使用calloc()而不是malloc(). 请注意,尽管没有将其设置为任何内容,但buffer[0].key.th_seq = 3131961357. 不是0。不是NULL。这是因为malloc()实例化了内存,但没有初始化它。如果您没有立即使用内存,那么谨慎的做法是在 ,memset(buffer, 0, MAX_SIZE * sizeof(key_value));之后调用malloc()以将所有已分配的内存位置清零。

例如:

(gdb) p buffer[2]
$3 = {key = {ip_src = 0x3021d0 "", ip_dst = 0x302210 "",
             th_sport = 0, th_dport = 0, th_seq = 0}, value = 0}

推荐阅读