我正在运行带有CCS7.2的TI-RTOS中的多个线程的应用程序,使用pthread
mutex
,condition
和thread
的实现。
它们都使用pvPortMalloc
动态分配内存。
为了保持我的线程很小,我正在动态地分配我的线程正在使用malloc
实现的更大内存块,以及pvPortMalloc
的另一个包装器。
其中有两个分配:
/* thread A ***************************/
#define CONST_ARRAY_SIZE 4
typedef struct {
uint16_t var1;
uint8_t var2;
uint32_t var3[CONST_ARRAY_SIZE];
/* ... */
/* sizeof(MyStruct) == 0x58 according to debugger */
} MyStruct;
MyStruct *p_myBuffer = malloc(sizeof(MyStruct)); // p_myBuffer = ucHeap + 0x40D0
/* thread B ***************************/
static pthread_mutex_t myMutex = NULL;
pthread_mutex_init(&myMutex); // myMutex = ucHeap + 0x4118 - why is this allowed?
问题很明显:只要p_myBuffer
初始化,myMutex
中的属性就会被覆盖。在第一个pthread_mutex_lock
上,互斥锁会进入configASSERT
,因为互斥锁的信号量已变为无效。
有没有什么可以让pvPortMalloc
“忘记”某些内存仍在使用或忘记块大小? 我想知道为什么系统允许在该堆地址处分配互斥内存,并将ucHeap + 0x40D0
和ucHeap + 0x4128
之间的地址视为可用。
堆管理是否会错误解释数组成员并且不计算所有元素的大小,而是计算一些指针大小?我用这个工具链对变量'sizeof
进行了一些奇怪的解释。
根据我对动态分配的了解,从堆分配的任何缓冲区(我正在使用heap4)应该保持不变并保持阻塞,以便在所有线程上进行进一步的分配。那些似乎没有这样做 - 是否有任何方式堆分配的内存块可以默默地超出范围并得到free
d?我调试到了可以排除显式free
的程度。
我遇到的一个可能相关的问题是,有时sizeof不能正常工作:
uint8_t integerSize = sizeof(uint32_t); // integerSize yields 4
uint32_t sampleInteger;
integerSize = sizeof(sampleInteger); // integerSize yields 1
我不确定哪种POD类型实际上导致了这种行为,但我记得它打破了一些缓冲区分配,并且它不是通常的数组/指针问题。有什么特别可能导致这种情况吗?这两个问题可以相关吗?毕竟,如果sizeof
返回的内容太小,malloc可能会在完全初始化时导致缓冲区溢出。