繁体   English   中英

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

[英]Why crash program by access pointer? In C

我试图访问一个指针,但是程序崩溃了。 随着内存访问错误。 我从堆栈收到指针。 (弹出功能)。 作为void *指针。 为什么我得到这种行为?

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;
}

更新:

我已经测试过我的堆栈了。 而且有效。 但是使用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;
}

您的堆栈实现中存在错误。 initStackgrow ,您都可以这样做:

malloc(sizeof(void) * max);

这是无效的,因为void没有大小,尽管某些编译器会将其评估为1。因此,您没有为void *数组分配足够的空间。 结果,您将在分配的内存末尾写入内容,从而调用未定义的行为

在两个地方都将要更改大小的类型更改为void *

malloc(sizeof(void *) * max);

问题是这种分配:

void initStack()
{

    array = malloc(sizeof(void) * max);
}

sizeof(void)是非法的,但是一些编译器认为它合法,例如gcc ,在这种情况下返回1 ,这对于您的int指针来说还不够。

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

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

致电

initStack(sizeof(int *));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM