【问题标题】:memcpy into a struct from char arraymemcpy 到 char 数组中的结构
【发布时间】:2016-02-12 03:15:11
【问题描述】:

我有一个char buffer[1024] 和一个结构

typedef struct {
   int record;
   int key;
} leaf_entry;

我试图实现的是缓冲区数组,它就像一个树的节点,它包含许多leaf_entry 条目。

如果我想向下迭代缓冲区以将缓冲区中的条目与另一个条目进行比较

for (i = 0; i < max_ents * entry_size; i += entry_size)
{
    leaf_entry curr;
    memcpy (curr, buffer[i], entry_size)
    if (curr == entry_to_compare)
       etc...
}

这是正确的吗?有没有更简单/更有效的方法来实现这一点?

【问题讨论】:

  • 为什么要使用 char buffer[] 而不是 struct leaf_entry buffer[]?
  • 为什么不是leaf_entry 的数组?为什么typedef 是一个结构?
  • char buffer[] 因为我的项目中的规范。我们正在将一个页面从磁盘“加载”到 1024 字节的主内存中。然后在那个页面中,我们想用包含 2 个整数的条目来填充它。
  • @JasonWoo 您将其标记为C++,而在 C++ 中,您不能随意使用 memcpy 结构。如果您的结构是non-POD,则您的示例会产生未定义的行为。在你的结构中粘贴一个std::string,那么 memcpy 就会变成一场灾难。
  • 在这种情况下,您可能会侥幸成功,因为结构只是简单的数据类型。不要尝试使用包含对象或指针的结构。也不要尝试使用对象。

标签: c++ c arrays memcpy


【解决方案1】:

鉴于您的结构是 POD,您应该能够在不复制的情况下执行此操作。

我相信这样的事情应该在 offset 是 char 缓冲区中正确的字节偏移量的情况下起作用:

leaf_entry & x = static_cast<leaf_entry &>(buffer + offset);

【讨论】:

  • 他是如何产生这个“偏移量”的?
  • 由于数据对齐而导致崩溃的可能性。在配备现代处理器的 PC 或嵌入式系统上,您可能只会招致性能损失。
  • @Nandu offset = n * sizeof(leaf_struct)
  • @user4581301 你是对的。也许,由于缓冲区包含所有整数,因此可以正确对齐以避免这种情况。
  • 但这不是数据在写入磁盘时在页面中序列化的方式。他正在以字节的形式读取所有内容。你怎么知道这是正确的顺序?
【解决方案2】:

我会考虑使用标准排序实现使用的方法 - 即使用接收 2 个指针的用户定义比较函数。然后,您可以使用这些指针来定位元素,并从那里访问和比较您感兴趣的成员。这也避免了不必要的内存复制。

考虑以下用于比较整数的函数:

int compareIntAsc(const void *int1, const void *int2)
{
    int *num1 = (int*)int1;
    int *num2 = (int*)int2;
    return *num1 - *num2;
}

现在考虑一个比较某些结构的计数成员的方法

int compareNodeCountAsc(const void *node1, const void *node1)
{
    return (pHuffmanNode)(node1))->charCount - ((pHuffmanNode)(node2))->charCount;
}

如果将数组中两个元素的地址传递给这样的函数,则可以比较记录或键。

例如,将元素 0 与其他所有元素进行比较

代码

typedef struct {
   int record;
   int key;
} leaf_entry, *pLeafEntry;

int compLeafKeyAsc(void *leaf1, void *leaf2)
{
    leaf_entry *p1, *p2;
    p1 = (leaf_entry *)leaf1;
    p2 = (leaf_entry *)leaf2;
    return p1->key - p2->key;
}

void printLeaf(pLeafEntry leaf)
{
    printf("----- leaf -------\n");
    printf("record: %d\n", leaf->record);
    printf("key: %d\n", leaf->key);
}

void demo()
{


    const int nElems = 16;
    leaf_entry leafArray[nElems];
    pLeafEntry firstElement;

    int i;
    for (i=0;i<nElems;i++)
    {
        leafArray[i].record = (rand()%51) + 100;        // record is [100..150]
        leafArray[i].key = (rand()%128);                // key is [0..127]
        printLeaf(&leafArray[i]);
    }

    //e.g  compare element 0 to every other element
    firstElement = &leafArray[0];
    for (i=1; i<nElems; i++)
    {
        printf("%d", firstElement->key );
        int result = compLeafKeyAsc(firstElement, &leafArray[i]);
        if (result < 0)
            printf(" is less than ");
        else if (result > 0)
            printf(" is greater than ");
        else
            printf(" is equal to ");
        printf("%d\n", leafArray[i].key);
    }
}

输出

----- leaf -------
record: 141
key: 35
----- leaf -------
record: 110
key: 4
----- leaf -------
record: 144
key: 108
----- leaf -------
record: 103
key: 46
----- leaf -------
record: 134
key: 16
----- leaf -------
record: 144
key: 113
----- leaf -------
record: 125
key: 59
----- leaf -------
record: 116
key: 107
----- leaf -------
record: 137
key: 38
----- leaf -------
record: 133
key: 60
----- leaf -------
record: 106
key: 12
----- leaf -------
record: 126
key: 25
----- leaf -------
record: 137
key: 94
----- leaf -------
record: 130
key: 28
----- leaf -------
record: 132
key: 55
----- leaf -------
record: 141
key: 94
35 is greater than 4
35 is less than 108
35 is less than 46
35 is greater than 16
35 is less than 113
35 is less than 59
35 is less than 107
35 is less than 38
35 is less than 60
35 is greater than 12
35 is greater than 25
35 is less than 94
35 is greater than 28
35 is less than 55
35 is less than 94

【讨论】:

  • 不要使用 C 风格的强制转换。使用static_cast。如果这不能编译,请再考虑一下您在做什么。
  • 很好,最近写了很多汇编。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-27
  • 1970-01-01
  • 2023-04-07
  • 2014-12-13
  • 2020-08-14
  • 1970-01-01
相关资源
最近更新 更多