【问题标题】:Get part of specific length of allocated memory space获取分配的内存空间的特定长度的一部分
【发布时间】:2016-12-21 09:36:43
【问题描述】:

我使用malloc() 将数十亿位加载到 RAM 中 - 将其称为 big_set。我在 RAM 中还有其他数量的位(将其称为 small_set),它们都设置为 1,我知道它的大小(多少位 - 我将其称为 ss_size ),但无法预测,因为每次执行都会有所不同。 ss_size 有时可能小至 100,也可能大至数亿。

我需要在 small_setss_size 位长度的 big_set 的一些 不可预测 部分之间进行一些按位运算.我不能仅仅扩展 small_set 在最重要和最不重要的边上都用零来使其大小等于 big_set 的大小,因为那将是非常 RAM 和CPU 成本高(相同的操作将同时使用许多不同大小的 small_set 进行,并且还会在 small_set 上进行移位操作,扩展它会导致更多位CPU 工作)。

例子:

big_set100111001111100011000111110001100(实际上是数十亿位)

small_set111111,所以 ss_size 为 6。(可能是不可预测的位数)。

我需要取 big_set 的 6 位长度部分,例如:001100000111 等 Obs.:不一定是第 N 6 位,它可以是从第 3 位到第 9 位, 例如。不知道怎么弄。

我不想得到一个 big_set 副本,除了我要占用的 6 位(例如 000000001111100000000000000000000)之外的所有内容都归零,因为那也会非常昂贵的 RAM。

问题是:我怎样才能从 big_set 内的任何地方获取 N 位,以便我可以在它们和 small_set 之间进行按位运算?成为 N = ss_size

【问题讨论】:

  • 问题是?
  • 我发现问题不在于将small_set 存储在内存中,而在于执行所需的操作(small_setbig_set 之间的按位操作)。您是否已经为 OR、AND、XOR 和其他操作编写了一些代码?
  • @VolAnd 我已经编写了大部分需要的按位运算,但是在我编写它们的时候,我正在扩展small_set,两边都用零,使其大小等于big_set 的大小。我刚刚注意到这不是一个好主意,因为 RAM 使用量很大,现在我想根据问题帖子中的描述进行更改。
  • 谈谈 XY 问题...由于小集合始终是 1 值的范围,因此有用的按位运算的数量在某种程度上是有限的(AND、XOR 是我首先想到的)。想想你的实际目标(从P 位置开始,从大集合中获取N 位)并实现它,而不是将问题变成位操作理论。
  • 您似乎在询问如何访问和修改大位字符串的子字符串。这是正确的吗?

标签: c malloc allocation


【解决方案1】:

我不确定下面给出的示例能否回答您的问题,我也不确定实现的 XOR 能否正常工作。

但我试图说明如果任务是节省内存,算法的实现会有多混乱。

这是big_set 中 40 位和small_set 中 6 位的示例:

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

void setBitsInMemory(uint8_t * memPtr, size_t from, size_t to)
// sets bits in the memory allocated from memPtr (pointer to the first byte)
// where from and to are numbers of bits to be set
{
    for (size_t i = from; i <= to; i++)
    {
        size_t block = i / 8;
        size_t offset = i % 8;
        *(memPtr + block) |= 0x1 << offset;
    }
}

uint8_t * allocAndBuildSmallSet(size_t bitNum)
// Allocate memory to store bitNum bits and set them to 1
{
    uint8_t * ptr = NULL;
    size_t byteNum = 1 + bitNum / 8; // determine number of bytes for  
    ptr = (uint8_t*) malloc(byteNum);
    if (ptr != NULL)
    {
        for (size_t i = 0; i < byteNum; i++) ptr[i] = 0;
        setBitsInMemory(ptr, 0, bitNum - 1);
    }
    return ptr;
}

void printBits(uint8_t * memPtr, size_t from, size_t to)
{
    for (size_t i = from; i <= to; i++)
    {
        size_t block = i / 8;
        size_t offset = i % 8;
        if (*(memPtr + block) & (0x1 << offset) )
            printf("1");
        else
            printf("0");
    }
}

void applyXOR(uint8_t * mainMem, size_t start, size_t cnt, uint8_t * pattern, size_t ptrnSize)
// Applys bitwise XOR between cnt bits of mainMem and pattern 
// starting from start bit in mainMem and 0 bit in pattern
// if pattern is smaller than cnt, it will be applyed cyclically
{
    size_t ptrnBlk = 0;
    size_t ptrnOff = 0;
    for (size_t i = start; i < start + cnt; i++)
    {
        size_t block = i / 8;
        size_t offset = i % 8;
        *(mainMem + block) ^= ((*(pattern + ptrnBlk) & (0x1 << ptrnOff)) ? 1 : 0) << offset;
        ptrnOff++;
        if ((ptrnBlk * 8 + ptrnOff) >= ptrnSize)
        {
            ptrnBlk = 0;
            ptrnOff = 0;
        }
        if (ptrnOff % 8 == 0)
        {
            ptrnBlk++;
            ptrnOff = 0;
        }
    }
}

int main(void)
{
    uint8_t * big_set;
    size_t ss_size;
    uint8_t * small_set;
    big_set = (uint8_t*)malloc(5); // 5 bytes (40 bit) without initialization
    ss_size = 6;
    small_set = allocAndBuildSmallSet(ss_size);
    printf("Initial big_set:\n");
    printBits(big_set, 0, 39);
    // some operation for ss_size bits starting from 12th
    applyXOR(big_set, 12, ss_size, small_set, ss_size);
    // output for visual analysis
    printf("\nbig_set after XOR with small_set:\n");
    printBits(big_set, 0, 39);
    printf("\n");
    // free memory
    free(big_set);
    free(small_set);
}

在我的电脑上,我可以看到以下内容:

【讨论】:

    猜你喜欢
    • 2018-08-16
    • 1970-01-01
    • 1970-01-01
    • 2022-07-23
    • 2012-04-12
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    相关资源
    最近更新 更多