从动态分配的内存打印时,值会更改

时间:2017-03-31 14:56:25

标签: c memory dynamic printing

好快速介绍。我正在做动态分配内存的功课。我们需要使用结构和dyn来模拟CPU。人。记忆。我正在测试我的堆栈是否正常运行并且没有溢出。堆栈应该是2 KiB,没有溢出,但是在打印数字时,很少有地址包含我没有输入的其他数字。我只是复制它,并删除指令列表,寄存器等等,这些都不是问题,而且会使这很长。

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

struct cpu {
    struct stack* memory;
};

struct stack {
    int32_t* values;
    int32_t* top;
};

void stackInit(struct stack* stack)
{
    stack->values = malloc(2048);
    stack->top = NULL;
}

void cpuInit (struct cpu* cpu)
{
    stackInit(cpu->memory); //initialize stack
}

void stackPush(struct stack* stack, int32_t value)
{
    if (stack->top == NULL){
        stack->top = stack->values;
        *(stack->top) = value;
    }
    else if (stack->top + sizeof(int32_t) < stack->values + 2048){
        stack->top += sizeof(int32_t);
        *(stack->top) = value;
    }
}

void cpuDebug(const struct cpu* cpu)
{    
    int32_t* auxpt = cpu->memory->top;

    if (cpu->memory->top != NULL)
        for (int32_t i = 0; auxpt >= cpu->memory->values; i++){ 

            printf("Value on the addr %d\n", *auxpt);
            printf("Address of auxpt: %p\n", ( void * )auxpt );
            auxpt -= sizeof(int32_t);
        }

    printf("\n");
}

int main()
{
    struct cpu Cpu;

    cpuInit(&Cpu);

    for (int32_t i = 0; i < 550; i++){
        stackPush(Cpu.memory,i);
    }

    cpuDebug(&Cpu);

    return 0;
}

输出如下:

Value on the addr 133
Address of auxpt: 0x562640529880
Value on the addr 10
Address of auxpt: 0x562640529870
Value on the addr 544108298
Address of auxpt: 0x562640529860
Value on the addr 2016419898
Address of auxpt: 0x562640529850
Value on the addr 1919181889
Address of auxpt: 0x562640529840
Value on the addr 128
Address of auxpt: 0x562640529830
Value on the addr 127

任何想法为什么会发生这种情况? 提前致谢

2 个答案:

答案 0 :(得分:4)

Man,您必须在访问其成员( top )之前分配struct stack。您正在访问非mallocated内存。

void stackInit(struct stack* stack)
{
    stack = malloc(sizeof(struct stack));
    stack->values = malloc(2048);
    stack->top = NULL;
}

遵循评论中指出的技巧,更好的解决方案可能是:

void stackInit(struct stack** stack)
{
    (*stack) = (struct stack*)malloc(sizeof(struct stack));
    (*stack)->values = (int32_t*)malloc(2048);
    (*stack)->top = NULL;
}

void cpuInit(struct cpu* cpu)
{
    stackInit(&cpu->memory); //initialize stack
}

通过这种方式,调用者将在Cpu.memory的上下文中看到已分配的内存。

答案 1 :(得分:3)

您的struct stack有一个关联的struct cpu,但该堆栈不是 cpuInit()的一部分; cpu只保存一个指向单独堆栈的指针。您永远不会初始化该指针,也不会为所需的堆栈保留任何内存。特别是,您的stackInit()功能不会执行此操作,而您的struct cpu { struct stack memory; // not a pointer }; 功能取决于它已经完成。

总的来说,假设每个cpu在其生命周期内只需要一个堆栈,那么最好将堆栈作为cpu的一个组成部分,这样你就不必担心这样的分配问题:

stackInit()

完成后,您需要更改通过cpu访问堆栈成员的语法,并且您需要注意其他语义差异,但是您可以总是通过&运算符获取指向堆栈的指针(例如传递给JAVA_TOOL_OPTIONS)。