指针算术导致错误的地址写入

时间:2020-05-17 23:19:56

标签: c arrays pointers malloc dynamic-memory-allocation

在这里,我尝试将下一个block_t的地址写入前一个块具有有效负载结构的地址。这只是一个PoC,稍后我将对其进行测试以集成到我的主代码中。但是,它不会将地址写到下一个块,而是将地址写到自身,如您在看到输出时会注意到的那样。

编辑1:所以我想这个问题归结为“我如何重用分配给有效负载的指针指向另一个块?”

#include <stdio.h>
#include <stdlib.h>

typedef unsigned word_t;

typedef struct block {
    word_t header;
    char payload[0];
} block_t;

static void set_next_free_block(block_t *block, block_t *nblock) {
    
    // Store the address of next block at the location where payload starts
    word_t *next_address = (word_t *)(block->payload);
    
    // Now write the address of next block here
    *next_address = nblock;
    
    return;
}

static block_t *get_next_free_block(block_t *block) {
    
    block_t *next_address = (block_t *)((word_t *)block->payload);
    
    return next_address;
}

int main() {
    block_t *block = (block_t *)malloc(sizeof(block_t));
    block_t *nblock = (block_t *)malloc(sizeof(block_t));
    block_t *next = NULL;
    set_next_free_block(block, nblock);
    next = get_next_free_block(block);
    printf("Block 1\nBlock address: %16x\n", (word_t)block);
    printf("Payload address: %16x\n", (word_t)block->payload);
    printf("Next: %16x\n", (word_t)next);
    printf("Block 2\nBlock address: %16x\n", (word_t)nblock);
    
    return 0;
}

我不明白为什么我在set_next_free_block内设置的指向nblock的地址所添加的地址指向错误的地址。

运行此命令时,我得到:

Output of above code

2 个答案:

答案 0 :(得分:1)

因此,使用功能set_next_free_block,您正在尝试将nblock的地址存储在block->payload中,对吧?

因此,我首先将char payload[0]更改为word_t以正确存储地址。 char payload[0]对我来说真的没有多大意义。

然后我只是将nblock指针放到word_t中以获取其地址并将其存储在block->payload中。

get_next_free_block函数中,您无需将block->payload强制转换为word_t *,然后再将其强制转换为block_t *

此代码是否提供您想要的结果?

#include <stdio.h>
#include <stdlib.h>

typedef unsigned word_t;

typedef struct block {
    word_t header;
    word_t payload;
} block_t;

static void set_next_free_block(block_t *block, block_t *nblock) {
    block->payload = (word_t)nblock;
    return;
}

static block_t *get_next_free_block(block_t *block) {
    return (block_t *)block->payload;
}

int main() {
    block_t *block = (block_t *)malloc(sizeof(block_t));
    block_t *nblock = (block_t *)malloc(sizeof(block_t));
    block_t *next = NULL;
    set_next_free_block(block, nblock);
    next = get_next_free_block(block);
    printf("Block 1\nBlock address:\t\t%16x\n", (word_t)block);
    printf("Payload address:\t%16x\n", (word_t)block->payload);
    printf("Next:\t\t\t%16x\n", (word_t)next);
    printf("Block 2\nBlock address:\t\t%16x\n", (word_t)nblock);
    getchar();

    return 0;
}

我得到以下信息:

Block 1
Block address:                   15a4a10
Payload address:                 15a4a48
Next:                            15a4a48
Block 2
Block address:                   15a4a48

答案 1 :(得分:0)

我实际上了解到,我尝试修改char有效负载[0]的方式非常不正确。虽然我们的作业使用GCC扩展名来允许声明长度为0的数组只是为了将指针添加到块结构,但是长度为0的数组应该是结构中的最后一个元素。

我没有在这里添加答案,因为这将以不道德的方式对家庭作业有所帮助,我只想告诉我们已经可以使用的内容:

如果我们想以多种方式使用此有效负载指针,则应改为在并集内声明它。