gpt4 book ai didi

c - armv5 上 c 中的指针分配错误

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:10:37 26 4
gpt4 key购买 nike

我在c中有以下代码:

LinkedList
MemAllocLinkedList_add(MemAllocLinkedList self, void* data)
{
LinkedList newElement = (LinkedList)
MemoryAllocator_allocate(self->ma, sizeof(struct sLinkedList));

if (newElement == NULL)
return NULL;

newElement->data = data;

newElement->next = NULL;

LinkedList listEnd = LinkedList_getLastElement((LinkedList) self);

listEnd->next = newElement;

return newElement;
}

char*
MemoryAllocator_allocate(MemoryAllocator* self, int size)
{
if (((self->currentPtr - self->memoryBlock) + size) <= self->size) {
char* ptr = self->currentPtr;
self->currentPtr += size;
return ptr;
}
else{
printf("MemoryAllocator_allocate: Out of Memory\n");
return NULL;
}
}

作为 LinkedList 指向 sLinkedList 的指针是:

struct sLinkedList {
void* data;
struct sLinkedList* next;
};

和 MemAllocLinkedList 指向 sMemAllocLinkedList 的指针,即:

struct sMemAllocLinkedList {
void* data;
struct sLinkedList* next;
MemoryAllocator* ma;
};

我有一个程序可以多次调用这个“MemAllocLinkedList_add”函数而没有问题,但是有一点,在这个函数中,赋值“listEnd->next = newElement”用 las 16 切换前 16 位,因此,我没有使用 listEnd->next 975912,而是使用 -467140594,这会在我稍后尝试访问该列表的最后一个元素时导致 SISEGEV 错误。

如果我编译它并在使用 debian(intel 64 位)的虚拟机和 raspberry pi(armv6 32 位)上运行它,它工作得很好。但是当我尝试使用带有 armv5tej 的 NanosG20 时,它会执行我已经解释过的操作。我使用 gcc 4.6。

有人知道为什么会这样吗?

谢谢。

编辑:

这是 LinkedList_getLastElement :

LinkedList
LinkedList_getLastElement(LinkedList list)
{int i=0;
while (list->next != NULL) {
list = list->next; i++;
}
return list;
}

类型内存分配器:

typedef struct {
char* memoryBlock;
char* currentPtr;
int size;
} MemoryAllocator;

此代码来自 libiec61850,是用于子电站的标准 61850 的实现,因此还有更多代码无法在此处发布。我只是发布出现错误的部分,但就像我说的那样,仅在带有 ARMv5 的板上,而不是在 VM 或 Raspberry Pi 上。

最佳答案

您实际上在所有 3 个平台上都遇到了同样的问题,只是在 Intel 和 ARMv6 上您得到了“看似正常工作”形式的未定义行为。

这是 C 标准的相关引用(我必须提交的 C99 的 n1256 草案中的 6.3.2.3):

A pointer to an object or incomplete type may be converted to a pointer to a different object or incomplete type. If the resulting pointer is not correctly aligned for the pointed-to type, the behavior is undefined.

“正确对齐”的概念由平台的 ABI 定义。在这种情况下,ARM ABI说 thar char 需要 1 字节对齐,而指针需要 4 字节对齐。由于 struct sLinkedList 由两个指针组成,因此它也必须至少与指针一样严格对齐。

现在,由于 MemoryAllocator_allocate 每次都会将其内部空闲指针递增 size,因此无法保证它返回的 char * 是任何东西优于 1 字节对齐,因此将其转换为 struct sLinkedList * 会在 3/4 可能的情况下导致未定义的行为。由于编译器往往比斗气更务实,而不是 nasal demons在取消引用它时,您得到了“无论硬件对未对齐的加载/存储做什么”的未定义行为,这可能是对齐错误,返回一些无意义的数据,甚至返回您期望的数据。

解决方案是使 MemoryAllocator_allocate 始终将 size 舍入到最接近的最大所需对齐的倍数 - 对于 ARM ABI,这是 8 个字节,但如果您确定您将永远使用任何 64 位类型(如 doublelong long),您可能可以使用 4 个字节。

关于c - armv5 上 c 中的指针分配错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26843923/

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