首页 > 解决方案 > 为什么整数数组中的一个值取消引用c中的随机值?

问题描述

我正在用 C 编写一个简单的整数堆栈实现,我将堆栈定义为:

typedef struct {
    int topIndex;
    int totalLength;
    int *elements;
} IntStack;

当我尝试遍历每个 intelements并访问它们或将它们从堆栈中弹出时,我的问题就出现了。

我的主要功能如下:

void main() {
    IntStack *mystack = createIntStack(10);
    int temp;

    for (int i=0; i<10; i++) {
        push(mystack, i);
    }

    printIntStack(mystack);
    printf("\n");

    for (int i=0; i<10; i++) {
        pop(mystack, &temp);
        printf("%d\n", temp);
    }

    destroyIntStack(mystack);
}

当我运行程序时,我将 0 到 9 压入堆栈,但是当我将元素弹出时,其中一个值会返回一些随机的大数。
这是输出:

9: 9 - top
8: 8
7: 7
6: 6
5: 5
4: 4
3: 874527284
2: 2
1: 1
0: 0

9
8
7
6
5
4
807406132
2
1
0

我无法弄清楚为什么其中一个值会像这样返回。当我更改代码并创建两个不同IntStack的变量时,输出会发生同样的事情,除了它是一个随机更改的不同数字。

我的其余实现代码如下(所有堆栈函数)

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

#define STACK_SUCCESS 0
#define STACK_FULL_ERR 1
#define STACK_EMPTY_ERR 2

typedef struct {
    int topIndex;
    int totalLength;
    int *elements;
} IntStack;

IntStack* createIntStack(int length) {
    IntStack *stack = malloc(sizeof(IntStack));
    int *stackElements = malloc(sizeof(int)*length);
    
    stack->topIndex = -1;
    stack->totalLength = length;
    stack->elements = stackElements;

    return stack;
}

void destroyIntStack(IntStack *stack) {
    free(stack->elements);
    free(stack);
}

void printIntStack(IntStack *stack) {
    for (int i=(stack->totalLength-1); i >= 0; i--) {
        if (i < stack->topIndex) {
            // element exists
            printf("%d: %d\n", i, *(stack->elements + sizeof(int)*i));
        } else if (i == stack->topIndex) {
            // element is top of stack
            printf("%d: %d - top\n", i, *(stack->elements + sizeof(int)*i));
        } else {
            // element is null
            printf("%d: NULL\n", i);
        }
    }
}

int push(IntStack *stack, int num) {
    if (stack->topIndex < stack->totalLength-1) {
        stack->topIndex += 1;
        memcpy((stack->elements + sizeof(int)*stack->topIndex), &num, sizeof(int));
        
        return STACK_SUCCESS;
    } else {
        return STACK_FULL_ERR;
    }
}

int pop(IntStack *stack, int *result) {
    if (stack->topIndex != -1) {
        memcpy(result, (stack->elements + sizeof(int)*stack->topIndex), sizeof(int));
        stack->topIndex -= 1;

        return STACK_SUCCESS;
    } else {
        return STACK_EMPTY_ERR;
    }
}

标签: arrayscpointersstackpointer-arithmetic

解决方案


您错误地使用了指针算法。例如让我们考虑函数push

int push(IntStack *stack, int num) {
    if (stack->topIndex < stack->totalLength-1) {
        stack->topIndex += 1;
        memcpy((stack->elements + sizeof(int)*stack->topIndex), &num, sizeof(int));
        
        return STACK_SUCCESS;
    } else {
        return STACK_FULL_ERR;
    }
}

stack->elements + sizeof(int)*stack->topIndex而不是调用中的表达式memcpy

memcpy((stack->elements + sizeof(int)*stack->topIndex), &num, sizeof(int));

你必须写

memcpy((stack->elements + stack->topIndex ), &num, sizeof(int));

虽然写起来会更简单和可读

stack->elements[stack->topIndex] = num;

这样的错误出现在程序的其他部分,例如这里

printf("%d: %d\n", i, *(stack->elements + sizeof(int)*i));

等等。

如果你有一个指向数组的指针

int a[2];
int *p = a;

那么表达式p + 1 的值大于该值所存储p的值sizeof( int )所以表达式p + 1指向数组的第二个元素a


推荐阅读