- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我在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 位类型(如 double
或 long long
),您可能可以使用 4 个字节。
关于c - armv5 上 c 中的指针分配错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26843923/
我的应用程序有问题。我收到 7 个 Apple Mach-O 链接器错误。以下是错误: Undefined symbols for architecture armv7: "_OBJC_IVAR_
我是一名优秀的程序员,十分优秀!