gpt4 book ai didi

c - 将不同类型的指针分配给现有内存

转载 作者:行者123 更新时间:2023-11-30 16:30:54 25 4
gpt4 key购买 nike

我尝试编写一个与类型无关的mem_take
它将需要预先分配的内存并将其 block 分配给多个指针。这些指针可以指向不同的类型:浮点型、 double 型等。

unsigned int mem_take( void** mem_input, void** mem_pos, const int size_bytes, const int alignment )
{
// get address
unsigned int addr = (unsigned int)*mem_pos;

// align
unsigned int adjustment_bytes = 0;
unsigned int misalignment = addr % alignment;
if(misalignment != 0)
{
adjustment_bytes = alignment - misalignment;
addr += adjustment_bytes;
}

// take aligned address
*mem_input = (void*)addr;

// move current position to next free location
addr += size_bytes;
*mem_pos = (void*)addr;

// return bytes taken
return (size_bytes + adjustment_bytes);
}

示例:

main()
{
char mem[SOME_SIZE];
void* mem_pos = mem;

float* f;
double* d;
int bytes_taken_f = mem_take((void**)&f , &mem_pos, 2 * sizeof(float) , 8); // 2 floats
int bytes_taken_d = mem_take((void**)&d , &mem_pos, 3 * sizeof(double), 8); // 3 doubles
// etc.

// now free to use the memory via arrays
f[0] = 1.0f;
f[1] = 2.0f;

d[0] = 1.0f;
d[1] = 2.0f;
d[2] = 3.0f;
}

这样做的原因是平台 - DSP 处理器,其内存非常有限。 (说来话长。)

这个解决方案有效吗? mem_take 写得正确吗?

附:请注意,实际用例是定点 DSP 处理器,因此上面的示例是“简化”的,类型不会是 float、double,而是特定于处理器的类型。

最佳答案

正在做:

 void f(void **f);
float a;
f((void**)&a);

不是一个好主意,因为void**不可移植。您需要获取 void* 变量的地址:

 void f(void **f);
float a;
void *tmp = &a;
f(&tmp);

,但你可以像 malloc 一样返回 void*!
这就像编写简单的 malloc 函数,在自定义堆栈上分配内存。

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

void *mem_take(void **mem, size_t *memsize, size_t nmemb, size_t size, size_t alignment, size_t *bytes_to_take)
{
assert(mem != NULL);
assert(nmemb != 0); // we can't "free"
assert(size != 0);
assert(alignment != 0);

// get array size
const size_t s = nmemb * size;
if (nmemb != 0 && s / nmemb != size) {
// overflow!
return NULL;
}

// align
const size_t rest = (size_t)((uintptr_t)*mem % alignment);
const size_t alignmentadd = rest == 0 ? 0 : alignment - rest;
// fprintf(stderr, "alignment %d %d %d %d\n", alignmentadd, ((uintptr_t)*mem % alignment), *memsize, s);

// inform of bytes we need to take
if (bytes_to_take != NULL) {
*bytes_to_take = alignmentadd + s;
}

// check free memory
if (*memsize < alignmentadd + s) {
//fprintf(stderr, "ENOMEM %d %d %d \n", *memsize, alignmentadd, s);
// ENOMEM!
return NULL;
}

// update state, get s + alignmentadd bytes, return ret
char *memc = *mem;
memc += alignmentadd;
void * const ret = memc;
memc += s;
*mem = memc;
*memsize -= alignmentadd + s;

return ret;
}

int main()
{
#define SOME_SIZE (sizeof(float) * 2 + 3 * sizeof(double) + 8)
char mem[SOME_SIZE];
void *mem_pos = mem;
size_t memsize = sizeof(mem);

float *f = mem_take(&mem_pos, &memsize, 2, sizeof(float), 8, NULL); // 2 floats
assert(f != NULL);
double *d = mem_take(&mem_pos, &memsize, 3, sizeof(double), 8, NULL); // 3 doubles
assert(d != NULL);
// etc.

// now free to use the memory via arrays
f[0] = 1.0f;
f[1] = 2.0f;

d[0] = 1.0f;
d[1] = 2.0f;
d[2] = 3.0f;

printf("%f %f %lf %lf %lf\n", f[0], f[1], d[0], d[1], d[2]);
}

关于c - 将不同类型的指针分配给现有内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50854468/

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