Why crash program by access pointer? In C - c

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

There is an error in your stack implementation. In both initStack and grow, you do this:
malloc(sizeof(void) * max);
This is invalid, as void doesn't have a size, although some compilers will evaluate this to 1. So you aren't allocating enough space for an array of void *. As a result, you write past the end of allocated memory which invokes undefined behavior.
Change the type you're getting the size of to void * in both places.
malloc(sizeof(void *) * max);

the issue is that kind of allocation:
void initStack()
{
array = malloc(sizeof(void) * max);
}
sizeof(void) is illegal but some compilers consider it legal like gcc, which in that case returns 1, which isn't enough for your int pointer.
So you could fix those by passing the size of the element:
void initStack(int sz)
{
array = malloc(sz * max);
call by
initStack(sizeof(int *));

Related

Use realloc() in function

#include <stdio.h>
#include <stdlib.h>
void Increase(int *array1,int *Nums) {
int*array2 = realloc(array1,(*Nums+1)*sizeof(int));
array2[*Nums] = 13;
array2[*Nums-1] = 14;
++(*Nums);
}
int main() {
int NumOfElements=0,i;
int*array=(int*)malloc(0*sizeof(int));
Increase(array,&NumOfElements);
for(i=0;i<NumOfElements;i++) {
printf("%d ", array[i]);
}
free(array);
}
How many elements will be in the array in main() if I run this program?
Does the Increase() function increase the number of memory cells of the array in main(), or will the array in main() still just have 0 memory cells?
From the realloc manual page:
The realloc() function returns a pointer to the newly allocated
memory, which is suitably aligned for any kind of variable and may be
different from ptr, or NULL if the request fails.
... so the answer to your question will depend on whether the call to realloc() was able to change the memory-allocation's size in-place, or not.
If realloc() was able to do an in-place resize (e.g. because the heap had allocated a larger-than-necessary array for the original malloc() call, allowing realloc() to simply mark some of the extra bytes in the buffer as in-use), then realloc() would return the same pointer that was passed in to it as an argument, which is the same memory-location that main() points to via array. In this scenario, main() could access the now-larger-array via array without any problems.
On the other hand, if realloc() wasn't able to do an in-place resize, then realloc() would be forced to allocate a newer/larger array, copy over the contents of the old array, free() the old array, and return the pointer to the larger array. In that case, array2 would point to a different location in memory than array and array1, and (worse), after Increase() returns, main() would invoke undefined behavior by dereferencing array, which is (at that point) a dangling pointer because realloc() freed the memory it used to point to.
I think one is intending to implement a common container known a dynamic array for use in a stack (or similar structure.)
#include <stddef.h>
struct int_stack { int *data; size_t size, capacity; };
struct int_stack int_stack(void);
void int_stack_(struct int_stack *);
int *int_stack_new(struct int_stack *);
This is what I'd use as int_stack.h. Notice that it's logical size and it's capacity are not necessarily the same, but size <= capacity.
#include "int_stack.h"
#include <stdlib.h>
#include <errno.h>
/** Initialises `s` to idle. */
struct int_stack int_stack(void) {
struct int_stack s;
s.data = 0;
s.capacity = s.size = 0;
return s;
}
/** Destroys `s`; returns it idle. */
void int_stack_(struct int_stack *const s) {
free(s->data);
*s = int_stack();
}
/** Ensures `min_capacity` of `s`. Returns success, otherwise, `errno` will be
set. */
static int int_stack_reserve(struct int_stack *const s, const size_t min) {
size_t c0;
int *data;
const size_t max_size = (size_t)-1 / sizeof *s->data, min_size = 3;
if(s->data) {
if(min <= s->capacity) return 1;
c0 = s->capacity < min_size ? min_size : s->capacity;
} else { /* Idle. */
if(!min) return 1;
c0 = min_size;
}
if(min > max_size) return errno = ERANGE, 0;
/* `c_n = a1.625^n`, approximation golden ratio `\phi ~ 1.618`. */
while(c0 < min) {
size_t c1 = c0 + (c0 >> 1) + (c0 >> 3);
if(c0 > c1) { c0 = max_size; break; }
c0 = c1;
}
if(!(data = realloc(s->data, sizeof *s->data * c0)))
{ if(!errno) errno = ERANGE; return 0; }
s->data = data, s->capacity = c0;
return 1;
}
/** Increases the capacity of `s` to at least `n` elements beyond the size.
Returns the start of the buffered space at the back of the array or null and
`errno`. */
static int *int_stack_buffer(struct int_stack *const s, const size_t n) {
if(s->size > (size_t)-1 - n) { errno = ERANGE; return 0; } /* Unlikely. */
return int_stack_reserve(s, s->size + n) && s->data ? s->data + s->size : 0;
}
/** Adds `n` elements to the back of `s` and returns a pointer to the elements.
Null indicates an error and `errno` will be set. */
static int *int_stack_append(struct int_stack *const s, const size_t n) {
int *buffer;
if(!(buffer = int_stack_buffer(s, n))) return 0;
return s->size += n, buffer;
}
/** Adds one new element of `s` and returns it as an uninitialized pointer or
null and `errno`. */
int *int_stack_new(struct int_stack *const s) { return int_stack_append(s, 1); }
This is an example of what I'd use as the implementation int_stack.c. The function int_stack_reserve is where the realloc is called once the size reaches the capacity. A temporary data is assigned the realloc; this is checked for error, then assigned into s->data. Reserving a geometrically increasing capacity will avoid the cost of expanding each time. Thus, the array will have amortized cost of O(n) to insert n elements.
#include <stdio.h>
#include <stdlib.h>
#include "int_stack.h"
int main(void) {
int status = EXIT_SUCCESS;
int *e1, *e2;
struct int_stack stack = int_stack();
if(!(e1 = int_stack_new(&stack)) || !(e2 = int_stack_new(&stack))) {
status = EXIT_FAILURE;
perror("stack");
} else {
*e1 = 13;
*e2 = 14;
for(size_t i=0; i<stack.size; i++) {
printf("%d ", stack.data[i]);
}
fputc('\n', stdout);
}
int_stack_(&stack);
return status;
}
Instead of a fixed-size, we now have unlimited size, but one has to check for out-of-memory condition.

Initialize array of pointers to NULL with realloc without iteration

Is it possible to automatically initialize to NULL the pointers inside an array reallocated with realloc without iterate over it? I would like to do something like calloc but i need te resize an already existent block of memory.
For example:
#DEFINE N 50
typedef int *pointerToInt;
typedef pointerToInt *pointerToPointer;
int main(){
pointerToInt p;
pointerToPointer pp;
pp = malloc(sizeof(p)*N);
//Now i want to resize and initialize my resized vector
pp = realloc(pp, sizeof(p)*(N+10));
}
In first approximation I could change the mallocto calloc, but when I use realloc there's nothing that guarantees me initialized pointers.
Is it necessary to iterate over the whole array and set each single pointer to NULL? Or there's a better way using only callocand realloc?
The short answer is: No, there is no standard function to reallocate a block of memory and initialize its newly allocated portion to all bits zero.
The solution is either:
to not require initialization by keeping track of the valid portion of the array. You obviously must have a way to do this, otherwise how would you decide to reallocate the object.
to initialize the newly allocated portion explicitly.
There are several problems in your code:
#DEFINE N = 50 is incorrect, it should just be #define N 50
hiding pointers behind typedefs is bad: it makes the code obscure and error prone. To do it twice is evil.
you did not include <stdlib.h>
you do not test for malloc failure
you do not initialize the array allocated by malloc() either.
Here is a modified version:
#include <stdlib.h>
#define N 50
int main(void) {
int i;
int **pp, **pp1;
pp = malloc(sizeof(*pp) * N);
if (pp) {
for (i = 0; i < N; i++) {
pp[i] = NULL;
}
//Now I want to resize and initialize my resized vector
pp1 = realloc(pp, sizeof(*pp) * (N + 10));
if (pp1) {
pp = pp1;
for (i = N; i < N + 10; i++) {
pp[i] = NULL;
}
}
free(pp);
}
return 0;
}
Note that you could write a utility function for your purpose:
#include <stdlib.h>
#include <string.h>
void *realloc_zero(void *p, size_t size, size_t new_count, size_t count, int *err) {
void *newp;
if (p == NULL)
count = 0;
newp = realloc(p, size * new_count);
if (newp == NULL) {
*err = 1;
return p;
} else {
if (new_count > count) {
memset((unsigned char*)newp + size * count, 0, size * (new_count - count));
}
*err = 0;
return newp;
}
}
#define N 50
int main(void) {
int err;
int **pp;
pp = calloc(sizeof(*pp), N);
...
//Now I want to resize and initialize my resized vector
pp = realloc_zero(pp, sizeof(*pp), N + 10, N, &err);
if (err) {
// could not resize
free(pp);
return 1;
}
...
free(pp);
return 0;
}
Note however that both calloc and realloc_zero initialize the block to all bits zero, which is not guaranteed by the C Standard to be a proper representation of NULL, although most current architectures do represent the null pointer this way.
No, there is no automatic way. You must iterate and set each uninitialized pointer.

in c, value is changing from the end of a function to outside the function after function call

In line 77 v->size is 0 while in line 186 v-size is 2. I dont understand why this is so because line 186 is at the very end of the function definition of void _setCapacityDynArr(struct DynArr *v, int newCap)(in line 140) and line 77 is right after the call to the function. Somehow between the end of the function and the next line after the function call the value has changed. I thought because v is a pointer it should retain the value. If someone could please tell me why the value is changing it would be greatly appreciated. I've run out of ideas and have no idea what to do.
http://pastebin.com/tWR6w8rG
/*
* File: main.c
* Author: user1
*
* Created on April 7, 2015, 3:57 PM
*/
#include <stdio.h>
#include <stdlib.h>
/*
* File: main.c
* Author: user1
*
* Created on April 7, 2015, 3:57 PM
*/
/*
*
*/
# ifndef TYPE
# define TYPE int
# endif
struct DynArr
{
TYPE *data;
int size;
int capacity;
};
/* pointer to the data array */
/* Number of elements in the array */
/* capacity ofthe array */
void initDynArr(struct DynArr *v, int capacity)
{
v->data = malloc(sizeof(TYPE) * capacity);
//assert(v->data != 0);
v->size = 0;
v->capacity = capacity;
}
void freeDynArr(struct DynArr *v)
{
if(v->data != 0)
{
free(v->data); /* free the space on the heap */
v->data = 0;
/* make it point to null */
}
v->size = 0;
v->capacity = 0;
}
int sizeDynArr( struct DynArr *v)
{
return v->size;
}
/*
void addDynArr(struct DynArr *v, TYPE val)
{
// Check to see if a resize is necessary
if(v->size == v->capacity)
_setCapacityDynArr(v, 2 * v->capacity);
v->data[v->size] = val;
v->size++;
}
*/
void addDynArr(struct DynArr *v, TYPE val)
{
// Check to see if a resize is necessary
if(v->size >= v->capacity)
{
_setCapacityDynArr(v, 2 * v->capacity);
printf(">>>%d",v->size); //<<<<<<<<<<<<<<<<<<<<v->size = 0
v->data[v->size] = val;
v->size++;
printf("setcapacity: size is: %d capacity is: %d value is %d value in array is: %d\n", v->size, v->capacity, val, v->data[v->size-1]);
}
else
{
v->data[v->size] = val;
v->size++;
printf("not setcapacity: size is: %d capacity is: %d value is %d value in array is: %d\n", v->size, v->capacity, val, v->data[v->size-1]);
}
//printf("%d\n", v->capacity);
}
void removeDynArray(struct DynArr *b, TYPE v)
{
for(int i = 0; i < b->size; i++)
{
if(b->data[i] == v)
{
while(i < (b->size))
{
b->data[i] = b->data[i+1];
i++;
}
break;
}
}
b->size--;
}
void print(struct DynArr *v)
{
for(int i = 0; i < v->size; i++)
{
printf("%d\n", v->data[i]);
}
}
//do this
void _setCapacityDynArr(struct DynArr *v, int newCap)
{
struct DynArr* temp;
temp = v;
///print(temp);
//struct DynArr v;
v = malloc(sizeof(struct DynArr));
v->data = malloc(sizeof(TYPE) * newCap);
v->capacity = newCap;
v->size = 0; //temp size is also being set
for (int i = 0 ; i < temp->size; i++)
{
v->data[i] = temp->data[i];
v->size++;
}
free(temp->data);
temp->size = 0;
temp->capacity = 0;
temp = 0;
printf(">!>>%d",v->size); //////////<<<<<<<<<<<<<<<<<<<<<<<<v->size = 2
}
int main(int argc, char** argv)
{
struct DynArr a;
initDynArr(&a, 2);
addDynArr(&a, 5);
addDynArr(&a, 7);
addDynArr(&a, 8);
//printf("%d\n", a.size);
//print(&a);
// printf ("%d\n",a.data[2]);
return (EXIT_SUCCESS);
}
Your _setCapacityDynArr function is written in a rather nonsensical fashion. All functions in this "API" receive a pointer v (or, sometimes, b) to an existing struct DynArr object, which they work with. They can manipulate the fields of *v object. They can allocate/deallocate/reallocate the actual array v->data. But they never allocate/deallocate the *v object itself. Object *v is passed from the outside and managed by the outside code.
But your _setCapacityDynArr function attempts to do something completely and drastically different. It begins with
temp = v;
v = malloc(sizeof(struct DynArr));
...
free(temp);
That is already incorrect. This is completely unacceptable. You are not allowed to allocate/deallocate *v object itself.
In any case, changing the value of v inside the function make no sense simply because v is passed to _setCapacityDynArr by value. The outside code will not see these changes anyway.
This latter detail is what makes your code to output allegedly "changing" value of v->size - you are simply outputing two completely different v->size values and one of them actually belongs to deallocated memory. In line 77 you are printing v->size value stored in "dead" memory already deallocated by free(temp) call inside _setCapacityDynArr.
Don't try to acclocate/deallocate *v object inside your _setCapacityDynArr. Where did you get that idea? Just reallocate v->data and change the other firelds accordingly. But don't attempt to change the value of v itself.

Generic stack in C using void pointer not working for strings

I am trying to implement a generic stack in C using void pointers. This is not anything big, just for fun and learning. It is working with int and float as expected. But the problem I am facing is with char *, i.e. strings. It is not copying the address of the string instead trying to copy the actual string upto 4 bytes(as in my system pointer size is 4 bytes).
How to tell C to copy address of the string not the actual string, if possible, with out breaking the functionality of int and float already working?
My implementation so far is as follows,
typedef struct{
int top;
void *data;
int capacity;
size_t ele_size;
}stack_t;
int stack_init(stack_t *s, int capacity, size_t ele_size)
{
/* Initializes the stack with the given capacity
* #param s: Pointer to stack_t type variable
* #param capacity: capacity of the stack to be created
* Returns : Zero if succesful in allocating memory to the stack,
* -1 Otherwise
*/
s->top = -1;
s->capacity = capacity;
s->ele_size = ele_size;
s->data = calloc(s->capacity, s->ele_size);
if (s-> data != NULL || s->capacity == 0) {
return 0;
} else {
return -1;
}
}
int stack_push(stack_t *s, void *x)
{
/* Pushes an element on to the stack
* #param s: Pointer to stack_t type variable
* #param x: Value to Push on to the stack
* Returns : Zero if stack is not full when stack_push() is called,
* -1 Otherwise
*/
if (stack_len(s) capacity) {
s->top++;
memcpy(s->data + s->ele_size * s->top, x, s->ele_size);
return 0;
} else {
return -1;
}
}
int stack_pop(stack_t *s, void *value)
{
/* Value that is popped from the stack is placed in value parameter,
* #param s: Pointer to stack_t type variable
* #param x: Pointer to a variable to store the value popped from the
stack
* Returns: Zero if stack is not empty when stack_pop() is called,
* -1 Otherwise
*/
if (stack_len(s) > 0) {
memcpy(value, s->data + s->ele_size * s->top, s->ele_size);
s->top--;
return 0;
} else {
return -1;
}
}
For complete implementation of stack please refer here
Usage of the above stack is as follows:
Actually there is lot of unrelated stuff like using pseudo random number generator to
insert random numbers into stack.
#include"../src/stack.h"
START_TEST(int_push_pop)
{
stack_t s;
int n = random() % 60267;
int *a = calloc(n, sizeof (int));
ck_assert_int_eq(stack_init(&s, n, sizeof (int)), 0);
int i;
for (i = 0; i = 0; i--) {
int value;
int x = stack_pop(&s, &value);
ck_assert_int_eq(x, 0);
ck_assert_int_eq(value, a[i]);
x = stack_len(&s);
ck_assert_int_eq(x, i);
}
stack_clear(&s);
stack_destroy(&s);
}
END_TEST
START_TEST(float_push_pop)
{
/* similar to int_push_pop, so ignored here. */
}
END_TEST
START_TEST(string_push_pop)
{
stack_t s;
char *str = "stack overflow";
stack_push(&s, str);
char **popval = malloc(sizeof(char *));
stack_pop(&s, popval);
printf("%s\n", popval);
stack_destroy(&s);
}
END_TEST
Suite* stack_suite()
{
Suite *s = suite_create("Stack");
TCase *tc_int = tcase_create("int");
/* Stack int data type Test Case*/
TCase *tc_float = tcase_create("float");
/* Stack float data type Test Case*/
tcase_add_test(tc_int, int_push_pop);
tcase_add_test(tc_float, float_push_pop);
suite_add_tcase(s, tc_int);
suite_add_tcase(s, tc_float);
return s;
}
int main()
{
int number_failed;
Suite *s = stack_suite();
SRunner *sr = srunner_create(s);
srunner_run_all(sr, CK_NORMAL);
number_failed = srunner_ntests_failed(sr);
srunner_free(sr);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
Since stack_push() and stack_pop() functions are taking a void* pointer, you will need to pass a pointer to the character array(string) that needs to be pushed and not the char array itself. e.g. if you declare your string as
char str[] = "hello world";
you will have to call the function as
stack_push(s,&str);

Retaining memory allocated in function body

In one of the programs, I created a function whose one argument was a pointer. The function dynamically allocated some memory to the pointer and returned the size of allocated memory along with other details. But, the allocated memory is destroyed as soon as the function is executed.
How can I retain access and data integrity outside the function to the memory allocated inside the function?
Here's the code modified after reading the replies:
void initialize(int **arr)
{
int i = 0;
*arr = malloc(sizeof(int) * 10);
for (; i < 10; ++i)
*arr[i] = i + 1;
for (i = 0; i < 10; ++i)
printf("\n%d", *arr[i]);
}
int main()
{
int i = 0;
int *arr;
initialize(&arr);
for (; i < 10; ++i)
printf("\n%d", arr[i]);
return 0;
}
But when I run it, it says "rr.exe has stopped working"; although it compiles successfully. Nothing gets printed, not even from the printf in the the function.
Do not call free() on the pointer received by the dynamical allocation, but return it from the function to the calling process.
Example:
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
/* give_me_memory(void ** ppv, size_t n) allocates n bytes to *ppv. */
/* The function returns 0 on success or -1 on error. On error errno is set accordingly. */
int give_me_memory(void ** ppv, size_t n)
{
if (NULL == ppv)
{
errno = EINVAL; /* Bad input detected. */
return -1;
}
*ppv = malloc(n);
if (NULL == *ppv)
{
return -1; /* malloc() failed. */
}
return 0; /* Getting here mean: success */
}
int main(void)
{
void * pv = NULL;
if (-1 == give_me_memory(&pv, 42))
{
perror("give_me_memory() failed");
return 1;
}
/* Do something with the 42 bytes of memory. */
free(pv);
return 0;
}
I guess your function looks like:
void f(int *pointer)
{
pointer = (int*)malloc(sizeof(int));
}
this is bad because, your function gets a copy of pointer. Imagine your function takes int as argument and changes its value. Original variable passed to function won't changed, because you passed it as a copy. Here We have the same - you can modify what's poitner pointing at, but not pointer itself.
What do we do when we want to pass variable to function so it can be changed inside? We pass it as a pointer. here You need to do the same - pass pointer to pointer:
void f(int **pointer)
{
*pointer = (int*)malloc(sizeof(int));
}
and call it like this:
int *p = 0;
f(&p);

Resources