Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C指针算术异常行为_C_Pointers_Pointer Arithmetic - Fatal编程技术网

C指针算术异常行为

C指针算术异常行为,c,pointers,pointer-arithmetic,C,Pointers,Pointer Arithmetic,我有以下看似简单的代码: void freeBin(MallocHeader * pBinHeader){ while(pBinHeader){ MallocHeader * pNext = pBinHeader->pNext; pBinHeader->magic = K_MAGIC_NUM; printf("Orig magic and size = %i %lu\n", pBinHeader->magic, pBinH

我有以下看似简单的代码:

void freeBin(MallocHeader * pBinHeader){
    while(pBinHeader){
        MallocHeader * pNext = pBinHeader->pNext;
        pBinHeader->magic = K_MAGIC_NUM;
        printf("Orig magic and size = %i %lu\n", pBinHeader->magic, pBinHeader->size);
        void * freeAddr = pBinHeader + sizeof(MallocHeader);
        MallocHeader * actual = freeAddr - sizeof(MallocHeader);
        printf("Pre free magic and size = %i %lu\n", actual->magic, actual->size);
        free(freeAddr);
        pBinHeader = pNext;
    }
}

第一个printf调用的输出与第二个printf调用的输出不匹配。但通过简单的运算,“实际”应该与“pBinHeader”匹配。我错过了什么?

您正在使用两种不同的指针算术方法

将1添加到
freeAddr
(键入void*)时,指针将递增1。
(这是一个扩展。在C中,void*指针不能用于指针算术)

将1添加到
pBinHeader
(键入MallocHeader*)时,指针将递增
sizeof(MallocHeader)

解决方案是使用正确的指针类型声明
pBinHeader

MallocHeader* freeAddr = pBinHeader + sizeof(MallocHeader);
MallocHeader * actual = freeAddr - sizeof(MallocHeader);
或投射指针:

void * freeAddr = pBinHeader + sizeof(MallocHeader);
MallocHeader * actual = (MallocHeader*)freeAddr - sizeof(MallocHeader);

您正在使用两种不同的指针算术方法

将1添加到
freeAddr
(键入void*)时,指针将递增1。
(这是一个扩展。在C中,void*指针不能用于指针算术)

将1添加到
pBinHeader
(键入MallocHeader*)时,指针将递增
sizeof(MallocHeader)

解决方案是使用正确的指针类型声明
pBinHeader

MallocHeader* freeAddr = pBinHeader + sizeof(MallocHeader);
MallocHeader * actual = freeAddr - sizeof(MallocHeader);
或投射指针:

void * freeAddr = pBinHeader + sizeof(MallocHeader);
MallocHeader * actual = (MallocHeader*)freeAddr - sizeof(MallocHeader);

我不确定到底出了什么问题,但在为分配器执行算术运算时,应该坚持使用
char*
指针。看看这是否有帮助。我想根据你接受的答案要求澄清这个问题。该解决方案将使
printf
语句匹配,但我想确保这是您想要的。是否要将指针从
pBinHeader
向前移动
sizeof(MallocHeader)
字节?或者通过计数
sizeof(MallocHeader)
单位,其中1单位是
pBinHeader的大小
?如果是后者,则接受的解决方案是正确的。如果是前者,您需要在执行算术之前将指针强制转换为
char*
,或从中添加/减去1。关于代码格式的建议:在声明或取消引用指针时,不要在
*
的两侧加空格。尽管编译器并不在意,但它在视觉上很混乱,使它看起来像是在乘法。例如,编写
MallocHeader*pNext
MallocHeader*pNext
。一些开发人员(比如我)更喜欢前者,其他人则使用后者。无论你选择哪一个,都要始终如一地使用它。这有助于明确您使用的是指针,而不是两个值的乘积。@bnaecker似乎喜欢它,可能会在指针执行后改变主意…@bnaecker我最终将1添加到pBinHeader以获得作为空指针的正确地址。我会处理格式。三年的不当行为很难纠正:(这种风格在我学习的Objective-C程序中更为常见。我不确定到底出了什么问题,但在为分配器进行算术运算时,你应该坚持使用
char*
指针。看看这是否有帮助。我想根据你接受的答案要求澄清这个问题。这种解决方案将使
优先于ntf
语句匹配,但我想确保这是您想要的。您想将指针从
pBinHeader
向前移动
sizeof(MallocHeader)
bytes?还是按
sizeof(MallocHeader)计数
units,其中1 unit是
pBinHeader
的大小?如果是后者,则公认的解决方案是正确的。如果是前者,则需要在执行算术之前将指针强制转换为
char*
,或从中加/减1。关于代码格式的建议:在声明或取消引用时,不要在
*
的两侧都加空格删除指针。即使编译器不在乎,它在视觉上也很混乱,使它看起来像是在乘法。例如,编写
MallocHeader*pNext
MallocHeader*pNext
。一些开发人员(比如我自己)更喜欢前者,其他人使用后者。无论你选择哪一个,都要始终如一地使用它。这有助于明确你是在使用指针,而不是将两个值相乘。@bnaecker似乎喜欢它,可能会在指针执行后改变主意…@bnaecker我最终将1添加到pBinHeader,以获得作为空指针的正确地址。我将处理格式化。三年的不当处理将很难纠正:(这种风格在我学习的Objective-C程序中更为常见。