gpt4 book ai didi

C 为双指针赋值

转载 作者:太空宇宙 更新时间:2023-11-04 03:23:45 26 4
gpt4 key购买 nike

我正在 stm32f103 微处理器上编写一些 C 代码。由于从堆中分配内存不稳定,因此不鼓励我使用 C 库函数 malloc()free() 等。相反,我想到了声明在编译期间提前一大块静态内存,并重新分配内存以满足我的伪动态内存分配目的。我的新 malloc 实现在我的计算机上测试时工作正常,但当我为双数据类型执行 malloc 时在 stm32 上崩溃。

这是我的 malloc 实现。我知道这不是真正的动态内存分配,但我这样做只是为了练习使用指针。

pk_malloc.c

#include "pk_malloc.h"

char pool[RESERVE];
void* alloc[RESERVE];

void mem_init()
{
for (int i = 0; i != RESERVE; i++)
{
alloc[i] = NULL;
}
}

void* mem_malloc(size_t size)
{
if (size > 0)
{
for (int i = 0; i != RESERVE; i++)
{
if (alloc[i] == NULL)
{
int end;
for (end = i; end != RESERVE; end++)
{
if (alloc[end] != NULL || end - i == size + 1)
{
break;
}
}
if (end - i == size + 1)
{
for (int k = i + 1; k != end; k++)
{
alloc[k] = &pool[k];
}
return alloc[i + 1];
}
}
}
}
return NULL;
}

void* mem_realloc(void* mem, size_t new_size)
{
if (mem == NULL)
{
return mem_malloc(new_size);
}
int old_size = 0;
void** alloc_t = &alloc[(char*)(mem) - pool];
while (*alloc_t != NULL)
{
old_size++;
alloc_t++;
}
if (new_size <= old_size)
{
mem_free((char*)mem + new_size);
return mem;
}
else
{
int i = alloc_t - alloc;
int size = new_size - old_size;
int end;
for (end = i; end != RESERVE; end++)
{
if (alloc[end] != NULL || end - i == size + 1)
{
break;
}
}
if (end - i == size + 1)
{
for (int k = i; k != end - 1; k++)
{
alloc[k] = &pool[k];
}
return alloc[i];
}
else
{
void* realloc_t = mem_malloc(new_size);
if (realloc_t == NULL)
{
return mem;
}
else
{
mem_copy(realloc_t, mem);
mem_free(mem);
return realloc_t;
}
}
}
}

void mem_copy(void* dest, void* source)
{
int dest_index = (char*)(dest) - pool;
int source_index = (char*)(source) - pool;
char* writer = (char*)(source);
while (alloc[source_index] != NULL && alloc[dest_index] != NULL)
{
pool[dest_index] = pool[source_index];
dest_index++;
source_index++;
}
}

void mem_free(void* mem)
{
if (mem != NULL)
{
void** alloc_t = &alloc[(char*)(mem) - pool];
while (*alloc_t != NULL)
{
*alloc_t = NULL;
alloc_t++;
}
}
}

pk_malloc.h

#ifndef _PK_MALLOC
#define _PK_MALLOC

#include <stdlib.h>

#define RESERVE 64

void mem_init();

void* mem_malloc(size_t size);
void* mem_realloc(void* mem, size_t new_size);

void mem_copy(void* dest, void* source);

void mem_free(void* mem);

#endif

主.c

int main()
{
mem_init();
int* hoho = (int*)(mem_malloc(sizeof(int)));
*hoho = 123;
printf("%d", *hoho);
mem_free(hoho);
}

代码在我的电脑上运行,在STM32上也运行。但是,当我将数据类型更改为 double 时:

int main()
{
mem_init();
double* hoho = (double*)(mem_malloc(sizeof(double)));
*hoho = 0.618;
printf("%f", *hoho);
mem_free(hoho);
}

它只适用于我的电脑,而它在 STM32 上崩溃了。

我做了一些测试和调试,我发现这一行有效,指针不为 NULL 并且它有一个有效地址。

double* hoho = (double*)(mem_malloc(sizeof(double)));

但是这条线崩溃了。

*hoho = 0.618;

经过更多测试,我发现任何占用超过 4 个字节的数据类型都会以同样的方式崩溃,包括 long long 等。

奇怪的是,我用很多intfloat等数据类型做了一些用户定义的结构,这肯定占用了4个字节以上,代码在STM32上运行良好.

struct ABC
{
int a;
float b;
};

这条线没问题。

struct ABC* hoho = (struct ABC*)(mem_malloc(sizeof(struct ABC)));

变量hoho可以被赋值,它的成员可以轻松访问,在我的电脑和STM32上都可以工作。

请注意,所有代码都适用于我的笔记本电脑,而且大多数数据类型也适用于 STM32。

我已经被这个问题困扰了几个小时,感谢任何帮助。

最佳答案

STM32F1 的核心是 Cortex-M3。这QA here指出虽然 Cortex-M3 允许对简单指令进行未对齐的字访问,not all instructions support unaligned access .在您的情况下,C 编译器使用不支持 double 未对齐地址的指令。

注意

  • 标准库 malloc 返回一个适当对齐的指针,以便可以将其分配给指向具有基本对齐要求的任何类型对象的指针,然后使用在分配的空间中访问此类对象或此类对象的数组” (C11 7.22.3)

  • 虽然一个指针可以转换为另一个指针,“如果生成的指针未针对引用类型正确对齐,则行为未定义” (C11 6.3.2.3p7) .

因此程序的行为在这些行已经是未定义的

int *hoho = mem_malloc(sizeof(int));
double *hoho = mem_malloc(sizeof(double));

如果返回的指针分别不适合 intdouble 对齐。

要修复代码,请对其进行更改,使其始终返回正确对齐的指针。官方 ARM 编译器 maintain an 8-byte aligned heap .

关于C 为双指针赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43052007/

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