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

C 从动态分配的内存打印时,值会更改,c,memory,dynamic,printing,C,Memory,Dynamic,Printing,好的,快速介绍。我正在做一个关于动态分配内存的家庭作业。我们需要使用structs和dyn来模拟CPU。记忆。我正在测试我的堆栈是否正常工作并且没有溢出。堆栈应该是2kib,没有溢出,但是在打印数字时,很少有地址包含我没有输入的其他数字。我把它复制到这里,去掉指令列表、寄存器等等,这些都不是问题,而且会让它变得很长 #include <stdlib.h> #include <stdio.h> #include <stdint.h> struct cpu {

好的,快速介绍。我正在做一个关于动态分配内存的家庭作业。我们需要使用structs和dyn来模拟CPU。记忆。我正在测试我的堆栈是否正常工作并且没有溢出。堆栈应该是2kib,没有溢出,但是在打印数字时,很少有地址包含我没有输入的其他数字。我把它复制到这里,去掉指令列表、寄存器等等,这些都不是问题,而且会让它变得很长

#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;
}
你知道为什么会这样吗?
提前感谢

Man,您必须先分配struct stack,然后才能访问其成员值和top。您正在访问未定位错的内存

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的上下文中看到分配的内存。

Man,在访问其成员值和top之前,必须分配struct stack。您正在访问未定位错的内存

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的上下文中看到分配的内存。

您的结构Cpu有一个关联的结构堆栈,但该堆栈不是结构Cpu的一部分;cpu仅持有指向单独堆栈的指针。您永远不会初始化该指针,也不会为想要的堆栈保留任何内存。特别是,您的cpuInit函数不这样做,而stackInit函数依赖于它已经完成了

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

struct cpu {
    struct stack memory;  // not a pointer
};
完成此操作后,您需要更改通过cpu访问堆栈成员的语法,并且需要注意其他语义差异,但您始终可以在需要时获得指向堆栈的指针,例如通过&operator传递给stackInit。

您的结构cpu具有关联的结构堆栈,但该堆栈不是struct cpu的一部分;cpu仅持有指向单独堆栈的指针。您永远不会初始化该指针,也不会为想要的堆栈保留任何内存。特别是,您的cpuInit函数不这样做,而stackInit函数依赖于它已经完成了

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

struct cpu {
    struct stack memory;  // not a pointer
};

完成此操作后,您需要更改通过cpu访问堆栈成员的语法,并且需要注意其他语义差异,但是,在需要的地方,您总是可以获得指向堆栈的指针,例如通过&operator传递给stackInit。

stack->values+2048返回的地址比stack->values高出2048*4字节。这远远超出了分配的空间。指针算法很复杂,这就是为什么您最好使用数组表示法和正确的类型。您正在处理堆栈结构中指向int32\t的指针。。。因此,当你向它加/减时,它是以sizeofint32字节为单位的,而不是以单个字节为单位的。因此,例如stack->top+=sizeofind32\t;按sizeofint32_t*sizeofint32_t字节递增,而不仅仅是sizeofint32_t字节。非常感谢。我记得.stack->values+2048返回的地址比stack->values高出2048*4字节。这远远超出了分配的空间。指针算法很复杂,这就是为什么您最好使用数组表示法和正确的类型。您正在处理堆栈结构中指向int32\t的指针。。。因此,当你向它加/减时,它是以sizeofint32字节为单位的,而不是以单个字节为单位的。因此,例如stack->top+=sizeofind32\t;按sizeofint32_t*sizeofint32_t字节递增,而不仅仅是sizeofint32_t字节。非常感谢。我会记住的。你是对的,但这不会起作用,因为调用函数不会获取stackInit的新值。为什么不呢?指针在stackInit外部是“可见”的,因为它是指针,而不是副本,调用方现在会处理位置不正确的内存,不是吗?不,@Pablo。指针指向的内容通过指针的其他副本在别处可见。指针值本身是一个类似于任何其他值的值-stackInit接收调用方值的副本,并且对函数副本的更改不会自动传回调用方。不,它应该是struct stack**stack,然后是*stack=mallocsizeofstruct stack;。或者我最好在cpu内部静态地分配堆栈,而不是指针..或者在CPUInit中调用malloc您是对的,但这不会起作用,因为调用函数不会获得stackInit的新值为什么不,指针在stackInit外部是“可见”的,因为它是指针,而不是副本,调用者现在将处理位置不正确的内存,不是吗?不,巴勃罗。指针指向的内容通过o在别处可见
指针的其他副本。指针值本身是一个类似于任何其他值的值-stackInit接收调用方值的副本,并且对函数副本的更改不会自动传回调用方。不,它应该是struct stack**stack,然后是*stack=mallocsizeofstruct stack;。或者我最好在cpu内部静态分配堆栈,而不是指针..或者在cpuInitYup中调用malloc,谢谢你指出,它不应该是指针,我的错。再次感谢:我们刚刚学习了指针,在我的代码中有很多“*”,我开始把它们放在任何地方:DYup,谢谢你指出,它不应该是指针,我的错。再次感谢:我们刚刚学习了指针,在我的代码中有很多“*”,我开始把它们放在任何地方:D