3

我正在尝试使用 C 进行编程。在我看来,一个巨大且重要的步骤是了解如何使用原始内存块,初始化它们并释放它们。在手头的测试程序中,我创建了两个结构,每个结构都有一个指针。

struct Address {
    int id;
    int var;
    char *name;
};

struct Link {
    int link_var;
    struct Address *addr;
};

在这种情况下,name 和 addr 是指针,因为我希望它们是动态大小的。

int main(int argc, char *argv[])
{    
    FILE *file = fopen("test.dat", "w");
    int i = 0;

    struct Link *link = malloc(sizeof(struct Link) + (sizeof(struct Address)*10) + (10*10));

    struct Address addr_container[10];

    for(i = 0; i < 10; i++) {

        char temp_name[10];
        memset(temp_name, '\0', 10);

        temp_name[0] = 'A';

        struct Address addr_proto = {.id = i, .var = 10, .name = temp_name};

        addr_container[i] = addr_proto;
    }

    struct Link link_proto = {.link_var = 2, .addr = addr_container};

    memcpy(link, &link_proto, sizeof(struct Link) + (sizeof(struct Address)*10) + (10*10));

    printf("%s\n", link->addr[4].name);



    int rc = fwrite(link, sizeof(struct Link) + (sizeof(struct Address)*10) + (10*10), 1, file);
    if(rc != 1) printf("Failed to write database.");

    fclose(file);
    free(link);

    return 0;
}

所以我在这里选择的方式是分配 *link 所需的所有内存。之后,我创建了一个链接结构的原型,其中所有数据都已初始化。(结构中的指针也指向初始化值)

之后,我将堆栈内存中原型中的所有数据复制到堆上的原始内存块中。与 memcpy。

当我写一个文件的链接时,Valgrind 对我大喊我要写未初始化的字节。

是因为我需要为结构中的所有指针单独分配内存吗?我不明白我如何编写一个包含我想要的所有链接和数据的文件。所以我可以阅读它并重新应用到一个新的空链接结构。

我是 C 的新手,这是学习内存分配的早期尝试,所以我很高兴每个批评我的代码的答案。我也确实在 stackoverflow 上搜索了答案,并找到了关于需要为结构中的指针分配内存的答案。但我无法弄清楚如何在代码中实现它。我还阅读了有关制作一个循环的信息,该循环将代码写入结构中的文件以及我需要的链接。这是最有效和最单一的方法吗?

顺便说一句:我需要使用指针,因为最后我希望这些指针可以使字符和地址结构数组的大小不同。

4

3 回答 3

2

为了“外部化”内存对象/数据结构,例如,当通过网络将对象发送到另一个进程或写入文件时,需要将内存对象格式化或转换为可移植表示。指针仅在进程的上下文中才有意义。

通常在发送或写入时将内存对象编码为可移植缓冲区,在接收或读取时将可移植缓冲区解码为内存对象。

几乎所有的 unix/linux/bsd 系统都将外部数据表示、XDR、库例程作为 libc 的一部分。执行“man xdr”以获取更多信息。

如果您使用 C 语言,xdr 非常适合。

于 2013-07-24T18:45:31.663 回答
0

您要实现的是序列化编组,通常在通过网络连接发送数据时完成,这在许多情况下增加了需要跨平台的复杂性。

这些天来,我认为您应该考虑使用Google Protocol Buffers来实现这一点,因为它会为您完成大部分繁重的工作。

iOS 或 OSX 特定的解决方案也可以是Core Data

从根本上说,这些指针在文件中是没有意义的,并且仅在单次调用期间与您的进程相关。

于 2013-07-24T13:05:42.650 回答
0

你可以试试这段代码:

 #include "stdio.h"

    struct Address {
        int id;
        int var;
        char *name;
    };

    struct Link {
        int link_var;
        struct Address *addr;
    };

    int main(int argc, char *argv[])
    {
        FILE *file = fopen("test.dat", "w");
        int i = 0;

        //struct Link *link = malloc(sizeof(struct Link) + (sizeof(struct Address)*10) + (10*10));//B2 + 10B1 +100
        struct Link *link = malloc(sizeof(struct Link));
        struct Address addr_container[10];

        for(i = 0; i < 10; i++) {

            char temp_name[10];
            memset(temp_name, '\0', 10);

            temp_name[0] = 'A';

            struct Address addr_proto = {.id = i, .var = 10, .name = temp_name};

            addr_container[i] = addr_proto;
        }

        struct Link link_proto = {.link_var = 2, .addr = addr_container};

        memcpy(link, &link_proto,sizeof(struct Link));// sizeof(struct Link) + (sizeof(struct Address)*10) + (10*10));

        printf("%s\n", link->addr[4].name);

        fprintf(file,"link_var : %d\n",(link->link_var));
        for(i = 0; i< 10; ++i)
        {
             fprintf(file,"Adress id is      :%d\n",(link->addr[i].id));
             fprintf(file,"Adress var is     :%d\n",(link->addr[i].var));
             fprintf(file,"Adress name is    :%s\n\n",(link->addr[i].name));
        }
        fclose(file);
        free(link);

        return 0;
    }

fwrite()二进制形式写入,所有数据的内存不是连续的!

于 2013-07-24T15:27:43.653 回答