마이크로 프로세서 stm32f103에서 일부 C 코드를 작성하고 있습니다. 힙에서 메모리를 할당하는 것이 안정적이지 않기 때문에 C 라이브러리 함수 malloc()
과 free()
등을 사용하지 않는 것이 좋습니다. 대신 컴파일 타임에 미리 큰 정적 메모리를 선언하고 메모리를 재 할당하여 내 가상 동적 메모리 할당 목적. 내 새로운 malloc 구현은 내 컴퓨터에서 테스트 할 때 잘 작동하지만 double 데이터 유형에 대해 malloc을 수행하면 stm32에서 충돌합니다.C가 이중 포인터에 값을 할당합니다.
다음은 내 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
main.c를
int main()
{
mem_init();
int* hoho = (int*)(mem_malloc(sizeof(int)));
*hoho = 123;
printf("%d", *hoho);
mem_free(hoho);
}
코드 내 컴퓨터에서 작동하고, 또한 STM32에서 작동합니다. 그러나 나는 두 번 내 데이터 유형을 변경하는 경우 : 내 컴퓨터에 그것은 단지 작동
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
등
를 포함하여 같은 방법으로, 충돌 발견, 나는 int
많은, float
데이터 유형과 일부 사용자 정의 구조체를 만든 분명히 4 바이트 이상을 차지하는 등, 코드는 STM32에서 정상적으로 작동합니다.
struct ABC
{
int a;
float b;
};
이 줄은 문제가 없습니다.
struct ABC* hoho = (struct ABC*)(mem_malloc(sizeof(struct ABC)));
변수 hoho
모든 코드는 내 랩톱에서 작동하며 대부분의 데이터 형식은 STM32에서도 작동합니다.
몇 시간 동안 문제가 발생하여 도움을 받으 셨습니다.
'이중'에 대한 정렬 요구 사항이있을 수 있습니다. – Ryan
정렬 요구 사항? 그것은 8 바이트가 double을 저장하기에 충분하지 않다는 것을 의미합니까? –
네, 어쩌면 코드를 해킹하여 모든 주소가 8로 정렬되도록해야합니다. 나는 그것이 충분한 지보기 위해 4 정렬을 시도 할 것이다. 또한'printf'가 충돌을 일으키지 않는지를 확인하기 위해 정적으로 할당 된 double을 출력 해보십시오. –