Why crash program by access pointer? In C

时间:2017-12-08 15:39:56

标签: c arrays pointers stack

I tried to access a pointer but the program crashes. With memory access error. I receive the pointer from a stack. (pop- function). As a void*-pointer. Why an I getting this behavior?

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

UPDATE:

I have tested my stack. And it works. But with for-loops it crashes.

My stack implementation. I get the error always I access to the pointer.

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

2 个答案:

答案 0 :(得分:3)

您的堆栈实施中存在错误。同时在initStackgrow中执行此操作:

malloc(sizeof(void) * max);

这是无效的,因为void没有大小,尽管有些编译器会将此值计算为1.因此,您没有为void *数组分配足够的空间。结果,您写入已分配内存的末尾,调用undefined behavior

将两个地方的大小改为void *

malloc(sizeof(void *) * max);

答案 1 :(得分:1)

问题在于那种分配:

void initStack()
{

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

sizeof(void)是非法的,但某些编译器consider it legal类似于gcc,在这种情况下返回1,这对于您的int指针是不够的。

所以你可以通过传递元素的大小来修复它们:

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

通过

打电话
initStack(sizeof(int *));