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;
}
答案 0 :(得分:3)
您的堆栈实施中存在错误。同时在initStack
和grow
中执行此操作:
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 *));