C doesn't put data in arrays or varibles - c

I'm the beginner in C programming< for now I'm using linux and tried both gcc and clang compilers. However, I'm facing the one problem, sometimes C doesn't put data in the array or variable. For example, there is one of my simple codes, that doesn't work completely:
#include <stdio.h>
#define size 10
struct stack{
int structTop;
int elemNum[size];
};
int create (struct stack s);
int full (struct stack s);
void push (int elem, struct stack s);
void main() {
struct stack s1;
struct stack s2;
struct stack s3;
int a = 545;
create(s1);
push(a, s1);
push(5, s1);
push(a, s1);
push(1, s1);
push(6, s1);
push(4, s1);
push(7, s1);
push(8, s1);
int i = 0;
while (i<4){
printf("%d\n", s1.elemNum[i]);
i++;
}
}
int create (struct stack s){
s.structTop = -1;
return 0;
}
int full(struct stack s){
if(s.structTop == size-1) {
return 1;
}
else {
return 0;
}
}
void push(int elem, struct stack s){
if(full(s)){
printf("Stack is full");
}
else {
s.structTop++;
s.elemNum[s.structTop]=elem;
}
}
As output I'm getting data, wich was inside array from the beginning (zeros or random numbers). Also it was only one of the codes, i have couple of larger ones, that have the same problem. Variables and arrays inside them are working 50/50, sometimes yes, sometimes no, even if declarations and functions are the same. Someone told me, that it could be the matter of compiler, but i tried different ones and also have a friend with the same Kali linux as me facing this problem on a different PC.

You need to pass pointers to the struct, i.e. int create (struct stack *s) instead of int create (struct stack s). The same for push. Otherwise, you pass a copy and in the function, you will alter a copy and not the originally passed object from main.
The thing why it sometimes worked, at least partially, is that when passing objects by value, these values will be put temporarily on a stack; It seems that the same object from main had several time been pushed right on the same position on the stack, such that it seemed as if it was always the same object. But - as you recognised - this really occasional.
The signatures of your methods should look as follows:
int create (struct stack *s);
int full (const struct stack *s);
void push (int elem, struct stack *s);
Note that - since passing now pointers - you have to access the elements of s using -> (and not .), e.g. s->structTop = -1 instead of s.structTop = -1; and that you have to pass the address of a stack (not the stack itself, e.g. push(a, &s1) instead of push(a, s1).
Note further that in int full (const struct stack *s), I declared s as const, as the function does not intend to alter any value of the members of s.
#include <stdio.h>
#define size 10
struct stack{
int structTop;
int elemNum[size];
};
int create (struct stack *s);
int full (const struct stack *s);
void push (int elem, struct stack *s);
int main() {
struct stack s1;
int a = 545;
create(&s1);
push(a, &s1);
push(5, &s1);
push(a, &s1);
push(1, &s1);
push(6, &s1);
push(4, &s1);
push(7, &s1);
push(8, &s1);
int i = 0;
while (i<4){
printf("%d\n", s1.elemNum[i]);
i++;
}
}
int create (struct stack *s){
s->structTop = -1;
return 0;
}
int full(const struct stack *s){
if(s->structTop == size-1) {
return 1;
}
else {
return 0;
}
}
void push(int elem, struct stack *s){
if(full(s)){
printf("Stack is full");
}
else {
s->structTop++;
s->elemNum[s->structTop]=elem;
}
}

Related

Creating pointer to a typedef stack

I am not able to initialize all three pointers to struct S, and I don't know why.
I am using a fixed-length array as stack to store values.
The header file is created this way to hide information (struct S), and should be kept as generic as possible.
main.c
// main.c
#include <stdio.h>
#include "stack_exercise4.h"
int main(void) {
Stack *stack_1, *stack_2, *stack_3;
int a, b;
make_empty(stack_1);
make_empty(stack_2);
make_empty(stack_3);
return 0;
}
Problem is, after Stack *stack_1, *stack_2, *stack_3, only stack_2 has a valid address for Struct stack. stack_1 and stack_3 have some strange looking addresses, and I can't assign any values to stack_1->top, nor stack_3->top. What is the problem?
header file
// stack_exercise4.h
#ifndef STACK_EXERCISE4_H
#define STACK_EXERCISE4_H
#include <stdbool.h> /* C99 only */
typedef struct S Stack; /* incomplete type to hide the content
of S. */
void make_empty(Stack *s);
bool is_empty(const Stack *s);
bool is_full(const Stack *s);
void push(Stack *s, int i);
int pop(Stack *s);
#endif
stack source file
// stack_exercise4a.c
#include "stack_exercise4.h"
#include <stdio.h>
#define MAX_STACK_SIZE (10)
struct S {
int top;
int contents[MAX_STACK_SIZE];
};
void make_empty(Stack *s) {
s->top = 0;
}
bool is_empty(const Stack *s) {
return (s->top <= 0);
}
bool is_full(const Stack *s) {
return (s->top >= MAX_STACK_SIZE - 1);
}
void push(Stack *s, int i) {
if (!is_full(s)){
(s->contents)[s->top++] = i;
} else {
printf("Failed to push, Stack is full.\n");
}
}
int pop(Stack *s) {
return (s->contents)[s->top--];
}
The stack pointers must point on memory spaces before being dereferenced in make_empty(). Something like this could be the starting point: make_empty() allocates the memory space.
void make_empty(Stack **s) {
(*s) = (struct S *)malloc(sizeof(struct S));
(*s)->top = 0;
}
And so the initialization of the pointers would be:
make_empty(&stack_1);
make_empty(&stack_2);
make_empty(&stack_3);
Declare stack_X on stack instead.
#include <stdio.h>
#include "stack_exercise4.h"
int main(void) {
Stack stack_1 = {0}, stack_2 = {0}, stack_3 = {0};
int a, b;
make_empty(&stack_1);
make_empty(&stack_2);
make_empty(&stack_3);
return 0;
}
Otherwise, I't would need to have constructor/destructor for your Stack data structure e.g new_stack(Stack *ptr) del_stack(Stack *ptr). For beginner, I would recommend to use stack instead of heap (stay away from malloc).

I'm trying to create a stack in c using structures but my push function doesn't work

I'm trying to create a stack in C using structures but the push() function I wrote is acting strangely. I'm sure it is something obvious that I'm missing but I just couldn't figure out what.
#include <stdio.h>
#define STACK_SIZE 50
typedef struct stack
{
int top;
int items[STACK_SIZE];
}
STACK;
void push(STACK* st, int newitem)
{
st->top++;
st->items[st->top] = newitem;
printf("%d", st->items[st->top]);
}
int main()
{
int n = 1;
STACK* st;
printf("test 1\n");
st->top = -1;
push(st, n);
printf("test 2\n");
return 0;
}
DevCpp only compiles but doesn't execute the code. OnlineGDB runs it but only prints the first test.
This is because your variable STACK* st; was never initialized properly.
Some Important Points:
Don't assign -1 to the length (top), 0 would be better
STACK* st; should be just STACK st;
Your function void push(STACK* st, int newitem) should be declared with static linkage.
Write st->top++
Pass st variable by address to the push() function
Instead of using bare return 0;, use return EXIT_SUCCESS;, which is defined in the header file stdlib.h.
As your total STACK_SIZE is only 50 so, int will be sufficient. But as your STACK_SIZE grows use size_t for your length(top).
use int main(void) { }, instead of int main() { }
NOTE: If STACK_SIZE and top becomes equal means your array is filled completely then further addition of data will lead to Undefined Behavior.
Final Code
#include <stdio.h>
#include <stdlib.h>
#define STACK_SIZE 50
typedef struct stack
{
int top;
int items[STACK_SIZE];
}
STACK;
static void push(STACK* st, int newitem)
{
if(st->top == STACK_SIZE)
{
fprintf(stderr, "stack size reached maximum length\n");
exit(EXIT_FAILURE);
}
st->items[st->top++] = newitem;
printf("%d\n", st->items[st->top - 1]); // we added +1 to `top` in the above line
}
int main(void)
{
int n = 1;
STACK st;
printf("test 1\n");
st.top = 0;
push(&st, n); //pass by address
return EXIT_SUCCESS;
}

How to fill a Stack with 0xAA?

I am trying to fill a stack (reserved by malloc) with the value 0xAA or 0b10101010. I think I manage to fill the stack, but printing it, I get different outputs (e83e83e83... or 41f41f41f... for example) depending on my stacksize.
Does anyone have an idea how to solve the problem?
int main(void) {
int status;
int stacksize = 1000;
void* stack=malloc(stacksize);
void* stackTop = stack + stacksize;
for(int i =0; i<stacksize;i++){
stackTop = "10101010";
stackTop --;
}
stackTop =stack + stacksize;
for(int i =0; i<stacksize;i++){
printf("%x", stacksize);
}
return 0;
}
It's somewhat hard to understand from your code and comments, what you're actually trying to do. But if I were to extrapolate on it, you're trying to create a "stack", with an element size of a byte. Here's a quick-and-dirty implementation of such a stack, with bounds checking:
#include <stdio.h>
#include <string.h>
#define STACK_SIZE 1000
struct stack {
int top;
unsigned char elts[STACK_SIZE];
};
static void stack_push(struct stack *s, unsigned char elt) {
if (s->top < STACK_SIZE-1) {
s->elts[s->top++] = elt;
} else {
// No space left in the stack.
}
}
static void stack_pop(struct stack *s) {
if (s->top) {
s->top--;
} else {
// Stack is empty
}
}
static void stack_fill(struct stack *s, unsigned char v) {
memset(s->elts, v, STACK_SIZE);
s->top = STACK_SIZE-1;
}
int main(void) {
// Example driver
struct stack s;
stack_fill(&s, 0xAA);
for (int i = 0; i < STACK_SIZE; i++) {
printf("%d: %02x\n", s.elts[s.top]);
stack_pop(&s);
}
return 0;
}
As an improvement, you could consider e.g. having stack_pop return the popped element, or return some kind of an error if the stack is empty. Or a peek function which returns the top, or an error similar to the one earlier described. However, I omitted them for brevity.
EDIT: To initialize the stack, the only thing required is to set the top member to 0. Initialization function (if needed) is thus trivial to write.
You are filling the stack with strings of chars and reading pointers to them.
The answer given by Paul Hankin in the comment states one of the correct solutions that is using
memset(stack, 0xAA, stacksize);
to fill your stack
thus producing the following code
int main()
{
int status;
int stacksize = 1000;
void* stack = malloc(stacksize);
void* stackTop = stack + stacksize;
memset(stack, 0xAA, stacksize);
for(int i =0; i < stacksize;i++){
printf("%x\n", ((unsigned char*)stack)[i]);
}
return 0;
}

C array struct function pointer

How do you create a function pointer with struct table such as
static struct {
int pid;
int queue[MAXPROCS];
} semtab[MAXSEMS];
I think I understand how to make OO equivalent in C using function pointer with this post, but how can I do with when my struct is an array. I'm still a little iffy with the syntax.
Would it be something like
static struct {
int pid;
int queue[MAXPROCS];
void (*fncPtr_enqueue)(int) = enqueue;
// or is it void(*enqueue)(semtable[]*) ?
int (*fcnPtr_dequeue)() = dequeue;
} semtab[MAXSEMS];
void enqueue(int i) { /* code */ }
int dequeue() { /* code */ }
// then to use it, it would be like this?
void foo() {
semtab[5].enqueue(6);
}
Use
static struct {
int pid;
int queue[MAXPROCS];
void (*fncPtr_enqueue)(int); // This defines a member fncPtr_enqueue
int (*fncPtr_dequeue)(); // Note that you had fcnPtr_ in your post.
// I have fncPtr_ here.
} semtab[MAXSEMS];
void enqueue(int i) { /* code */ }
int dequeue() { /* code */ }
Each object in semtab that needs to have valid function pointers needs to be updated.
semtab[0].fncPtr_enqueue = enqueue;
semtab[0].fncPtr_dequeue = dequeue;
You could use:
static struct
{
int pid;
int queue[MAXPROCS];
void (*enqueue)(int);
int (*dequeue)(void);
} semtab[MAXSEMS];
void enqueue(int i) { /* code */ }
int dequeue(void) { /* code */ }
void foo(void)
{
semtab[5].enqueue(6);
}
Changes include:
Systematic names for structure member pointers (instead of mixed fncPtr and fcnPtr prefixes).
No attempt to initialize in the structure definition.
Add void to function prototypes to indicate no arguments. In C (and in contrast to C++), an empty pair of brackets (parentheses) means "a function taking an undefined number of arguments, but not one which has a variable argument list with ... ellipsis".
Because of (1), the original invocation is OK. (With the original code, you'd have needed semtab[5].fncPtr_enqueue(6); — or even (*semtab[5].fncPtr_enqueue)(6);)
You would still have to ensure that the function pointers in the table are all initialized.
With GCC and C99 or C11 compilation, you could initialize the array using:
static struct
{
int pid;
int queue[MAXPROCS];
void (*enqueue)(int);
int (*dequeue)(void);
} semtab[MAXSEMS] =
{
[0 ... MAXSEMS-1] = { .enqueue = enqueue, .dequeue = dequeue }
};
The [0 ... MAXSEMS-1] part is a GCC extension. Observe that a space is required after the 0 to avoid problems with the 'maximal munch' rule.
As JS1 mentioned in the comments, it's actually pretty pointless to do this with the example you have, as you're not achieving anything with the indirection if you're not going to vary the value of those pointers.
That being said, here's an example using a stack (because the logic is easier than a queue, and this is a simple example). Note that you must pass a pointer to the stack to each of your member functions, because while C++ member functions have an implicit this argument, C functions never do. You also need to give your struct a name, otherwise you won't be able to refer to it in the abstract, which you need to do.
This program uses the same struct to implement two variations of a stack, one normal one, and one which unnecessarily shouts at you when you push or pop:
#include <stdio.h>
#include <stdlib.h>
enum {
STACKSIZE = 1024
};
struct stack {
int stack[STACKSIZE];
size_t top;
void (*push)(struct stack *, int);
int (*pop)(struct stack *);
void (*destroy)(struct stack *);
};
void stack_push(struct stack * this, int i)
{
if ( this->top == STACKSIZE ) {
fprintf(stderr, "Queue full!\n");
exit(EXIT_FAILURE);
}
this->stack[this->top++] = i;
}
void stack_push_verbose(struct stack * this, int i)
{
stack_push(this, i);
printf("** PUSHING %d ONTO STACK! **\n", i);
}
int stack_pop(struct stack * this)
{
if ( this->top == 0 ) {
fprintf(stderr, "Stack empty!\n");
exit(EXIT_FAILURE);
}
return this->stack[--this->top];
}
int stack_pop_verbose(struct stack * this)
{
const int n = stack_pop(this);
printf("** POPPING %d FROM STACK! **\n", n);
return n;
}
void stack_destroy(struct stack * this)
{
free(this);
}
struct stack * stack_create(void)
{
struct stack * new_stack = malloc(sizeof * new_stack);
if ( !new_stack ) {
perror("Couldn't allocate memory");
exit(EXIT_FAILURE);
}
new_stack->top = 0;
new_stack->push = stack_push;
new_stack->pop = stack_pop;
new_stack->destroy = stack_destroy;
return new_stack;
}
struct stack * stack_verbose_create(void)
{
struct stack * new_stack = stack_create();
new_stack->push = stack_push_verbose;
new_stack->pop = stack_pop_verbose;
return new_stack;
}
int main(void)
{
struct stack * stack1 = stack_create();
struct stack * stack2 = stack_verbose_create();
stack1->push(stack1, 4);
stack1->push(stack1, 3);
stack1->push(stack1, 2);
printf("Popped from stack1: %d\n", stack1->pop(stack1));
stack2->push(stack2, 5);
stack2->push(stack2, 6);
printf("Popped from stack2: %d\n", stack2->pop(stack2));
printf("Popped from stack1: %d\n", stack1->pop(stack1));
printf("Popped from stack1: %d\n", stack1->pop(stack1));
printf("Popped from stack2: %d\n", stack2->pop(stack2));
stack1->destroy(stack1);
stack2->destroy(stack2);
return 0;
}
with output:
paul#horus:~/src/sandbox$ ./stack
Popped from stack1: 2
** PUSHING 5 ONTO STACK! **
** PUSHING 6 ONTO STACK! **
** POPPING 6 FROM STACK! **
Popped from stack2: 6
Popped from stack1: 3
Popped from stack1: 4
** POPPING 5 FROM STACK! **
Popped from stack2: 5
paul#horus:~/src/sandbox$
Note that we use the exact same struct stack for both types of stack - the differences between them are implemented by having the function pointers point to different functions in each case. The only visible difference to the user is that one is created with stack_create(), and the other is created with stack_create_verbose(). In all other respects, they're used identically, so you can see the polymorphism at work.

void pointers and ffcall library

I'm using the ffcall (specifically the avcall package of ffcall) library to dynamically push parameters to variadic functions. i.e. we have
int blah (char *a, int b, double c, ...);
and we want to call this function with values taken from the user. To do this, we create an avcall version of the function:
int av_blah (char *a, int b, double c, char **values, int num_of_values)
{
av_alist alist;
int i, ret;
av_start_int (alist, &blah, &ret); //let it know which function
av_ptr (alist, char*, a); // push values onto stack starting from left
av_int (alist, b);
av_double (alist, c);
for (i=0;i<num_of_values;i++)
{
// do what you want with values and add to stack
}
av_call (alist); //call blah()
return (ret);
}
Now, the function I am using avcall with is:
int read_row (struct some_struct *a, struct another_struct *b[], ...);
And it is used like so:
struct some_struct a;
struct another_struct **b = fill_with_stuff ();
char name[64];
int num;
while (read_row (&a, b, name, &num)==0)
{
printf ("name=%s, num=%d\n", name, num);
}
But I want to use avcall to capture a certain amount of values from this function and I do not know this information in advance. So I thought I'd just create an array of void pointers and then malloc space according to the type:
char printf_string[64]=""; //need to build printf string inside av_read_row()
void **vals = Calloc (n+1, sizeof (void*)); //wrapper
while (av_read_row (&a, b, vals, n, printf_string) == 0)
{
// vals should now hold the values i want
av_printf (printf_string, vals, n); //get nonsense output from this
// free the mallocs which each vals[i] is pointing to
void **ptrs = vals;
while (*ptrs) {
free (*ptrs); //seg faults on first free() ?
*ptrs=NULL;
ptrs++;
}
//reset printf_string
printf_string[0]='\0';
printf ("\n");
}
And av_read_row is just:
int av_read_row (struct some_struct *a, struct another_struct *b[], void **vals, int num_of_args, char *printf_string)
{
int i, ret;
av_alist alist;
av_start_int (alist, &read_row, &ret);
av_ptr (alist, struct some_struct *, a);
av_ptr (alist, struct another_struct **, b);
for (i=0;i<num_of_args;i++)
{
switch (type) //for simplicity
{
case INT: {
vals[i] = Malloc (sizeof (int));
av_ptr (alist, int*, vals[i]);
strcat (printf_string, "%d, ");
break;
}
case FLOAT: {
//Same thing
}
//etc
}
}
av_call (alist);
return (ret);
}
I have been experiencing a bunch of memory corruption errors and it seems as though it doesn't like what I'm doing here. I can't spot anything wrong with the way I did this, can you? At the moment, it doesn't like it when I try to free the mallocs inside the av_read_row while loop. Can anyone see what I'm doing wrong, if anything?
Thanks
The only information I can easily find about avcall is from 2001, but it does suggest POSIX. If you can run your stuff on Linux, valgrind will find your memory faults in a jiffy. It's a terrific tool.
I did not go into the finer details of the code, but can say the following
Using stack for passing large number of arguments is not advisable, as stack is limited. I am not sure if av_stuff really checks the stack limit.
Isn't there a simpler method to do the same operation instead of pushing the variable to stack?

Resources