为什么通过访问指针使程序崩溃?在C中

为什么通过访问指针使程序崩溃?在C中,c,arrays,pointers,stack,C,Arrays,Pointers,Stack,我试图访问指针,但程序崩溃了。内存访问错误。 我从堆栈接收指针。(pop-功能)。作为空*指针。 为什么我会有这种行为? int main() { int MAX = 5; int field[MAX]; int i; /* for the loop */ int *pInt = NULL; initStack(); for (i = 0; i < MAX; i++) { field[i] = i;

我试图访问指针,但程序崩溃了。内存访问错误。 我从堆栈接收指针。(pop-功能)。作为空*指针。 为什么我会有这种行为?

int main()
{
    int MAX = 5;
    int field[MAX];
    int i; /* for the loop */
    int *pInt = NULL;

    initStack();

    for (i = 0; i < MAX; i++)
    {
        field[i] = i;
        push((field + i));  // HERE CRASH
    }

    for (i = 0; i < MAX; i++)
    {
        pInt = pop();   /* fetch next integer */

        printf("%d\n", *pInt); /* print value */
    }



    return EXIT_SUCCESS;
}
intmain()
{
int MAX=5;
int字段[MAX];
int i;/*用于循环*/
int*pInt=NULL;
initStack();
对于(i=0;i
更新:

我已经测试了我的堆栈。它是有效的。但在for循环中,它崩溃了

我的堆栈实现。 当我访问指针时,总是会出现错误

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

#include "stack.h"

/* 
   actual stack data structure
   This pointer will pointing at the actual field (of void * pointers) 
   that represents the stack.
 */
void **array;

/* the current capacity of the stack */
int max = 10;

/* counter variable for counting the elements of the stack. */
int counter = 0;

/* 
    offset address 
    points at the top element of the stack.
*/
int offset = -1;

void initStack(void)
{

    array = malloc(sizeof(void) * max);
    assert(array); /* tests whether pointer is assigned to memory. */
}

/*
    grow: increases the stack by 10 elements.
          This utility function isn't part of the public interface
*/
void grow(void)
{
    max += 10; /* increases the capacity */

    int i; // for the loop
    void **tmp = malloc(sizeof(void) * max);

    /* copies the elements from the origin array in the new one. */
    for (i = 0; i < max - 10; i++)
    {
        *(tmp + i) = *(array + i);
    }

    array = tmp; /* setups the new one as basis */
}

/* push: pushs the argument onto the stack */
void push(void *object)
{

    assert(object); /* tests whether pointer isn't null */

    if (offset < max)
    {

        offset++; /* increases the element-pointer */

        /* 
            moves pointer by the offset address 
            pushes the object onto stack 
         */
        *(array + offset) = object;
    }
    else /* stack is full */
    {

        /* TODO */
        grow();
        push(object); /* recursive call */
    }
}

/*
    pop: pops the top element of the stack from the stack.
*/
void *pop(void)
{
    printf("\tBEFORE\n"); //DEBUG
    void *top = *(array + offset);
    assert(top);
    assert(array + offset);
    printf("\tAFTER  void *top = *(array + offset);\n"); //DEBUG
    // int *pInt = top;
    // printf("\tpop: value= %d\n", *top); /* DEBUG */

    /* decreases the offset address for pointing of
        the new top element */
    offset--;

    return top;
}
#包括
#包括
#包括
#包括“stack.h”
/* 
实际堆栈数据结构
此指针将指向实际字段(由void*指针组成)
表示堆栈的。
*/
空**数组;
/*堆栈的当前容量*/
int max=10;
/*用于计算堆栈元素的计数器变量*/
int计数器=0;
/* 
偏移地址
指向堆栈的顶部元素。
*/
整数偏移量=-1;
void initStack(void)
{
数组=malloc(sizeof(void)*max);
断言(数组);/*测试指针是否分配给内存*/
}
/*
增长:将堆栈增加10个元素。
此实用程序函数不是公共接口的一部分
*/
虚空增长(虚空)
{
最大+=10;/*增加容量*/
int i;//用于循环
void**tmp=malloc(sizeof(void)*最大值);
/*将原始数组中的元素复制到新数组中*/
对于(i=0;i
问题在于这种分配:

void initStack()
{

    array = malloc(sizeof(void) * max);
}
sizeof(void)
是非法的,但是一些编译器,如
gcc
,在这种情况下返回
1
,这对于
int
指针来说是不够的

因此,您可以通过传递元素的大小来修复这些问题:

void initStack(int sz)
{
    array = malloc(sz * max);
拜访

initStack(sizeof(int *));

问题在于这种分配:

void initStack()
{

    array = malloc(sizeof(void) * max);
}
sizeof(void)
是非法的,但是一些编译器,如
gcc
,在这种情况下返回
1
,这对于
int
指针来说是不够的

因此,您可以通过传递元素的大小来修复这些问题:

void initStack(int sz)
{
    array = malloc(sz * max);
拜访

initStack(sizeof(int *));

堆栈实现中存在错误。在
initStack
grow
中,您可以执行以下操作:

malloc(sizeof(void) * max);
这是无效的,因为
void
没有大小,尽管有些编译器会将其计算为1。因此,您没有为
void*
数组分配足够的空间。因此,您的写入超过了调用的已分配内存的末尾

在这两个位置将要获取大小的类型更改为
void*

malloc(sizeof(void *) * max);

堆栈实现中存在错误。在
initStack
grow
中,您可以执行以下操作:

malloc(sizeof(void) * max);
这是无效的,因为
void
没有大小,尽管有些编译器会将其计算为1。因此,您没有为
void*
数组分配足够的空间。因此,您的写入超过了调用的已分配内存的末尾

在这两个位置将要获取大小的类型更改为
void*

malloc(sizeof(void *) * max);

寻求调试帮助的问题(为什么此代码不起作用?)必须包括所需的行为、特定的问题或错误以及在问题本身中重现这些问题所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:如何创建。
(int*)pop()
此地址必须无效。很好。@ChristianBender不清楚字段是如何声明和定义的。@Jean-Françoisfare我已经删除了(int*),但仍然有错误。@Vladfrommosco抱歉。我已经更新了我的评论。寻求调试帮助的问题(为什么这段代码不起作用?)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:如何创建。
(int*)pop()
此地址必须无效。很好。@ChristianBender不清楚字段是如何声明和定义的。@Jean-Françoisfare我已经删除了(int*),但仍然有错误。@Vladfrommosco抱歉。我已经更新了我的评论。也许值得注意的是,这种混淆通常可以通过直接参考所分配元素的大小来避免。例如,
array=malloc(sizeof(*array)*max)
。如果以后更改了
数组
指向的类型,这种情况甚至会继续存在。每当您对指针进行操作时,始终添加空检查并同时推送字段+i将在i值最大值为-1时成为无效索引。例如,如果您是accesi,则您拥有的数组[5]的id现在的有效索引将为0到5