I have some C code, and I’m not quite sure what’s going on.
#include <stdio.h>
#include <stdlib.h>
#define DIM1 7
#define DIM2 5
#define RES_SIZE 1000
typedef double stackElementT;
typedef struct {
stackElementT *contents;
int maxSize;
int top;
int min2;
} stackT;
void StackInit(stackT *stackP, int maxSize) {
stackElementT *newContents;
newContents = (stackElementT *)malloc(sizeof(stackElementT)*maxSize);
if (newContents == NULL) {
fprintf(stderr, "Not enough memory.\n");
exit(1);
}
stackP->contents = newContents;
stackP->maxSize = maxSize;
stackP->top = -1;
}
void StackDestroy(stackT *stackP) {
free(stackP->contents);
stackP->contents = NULL;
stackP->maxSize = 0;
stackP->top = -1;
}
int StackIsEmpty(stackT *stackP) { return stackP->top < 0; }
int StackIsFull(stackT *stackP) { return stackP->top >= stackP->maxSize-1; }
void StackPush(stackT *stackP, stackElementT element) {
if(StackIsFull(stackP)) {
fprintf(stderr, "Can't push element: stack is full.\n");
exit(1);
}
stackP->contents[++stackP->top] = element;
}
stackElementT StackPop(stackT *stackP) {
if(StackIsEmpty(stackP)) {
fprintf(stderr, "Can't pop element: stack is empty.\n");
exit(1);
}
return stackP->contents[stackP->top--];
}
int shell(char* s1, int arg) {
printf("> ");
scanf("%s %d%*c", &s1, &arg);
return arg;
}
int main() {
char cmds[DIM1][DIM2] = {{"push"}, {"pop"}, {"add"}, {"ifeq"}, {"jump"}, {"print"}, {"dup"}};
char* s1; int arg;
arg = shell(s1, arg);
printf("%s\n", &s1);
}
Input: push 4. It prints J+ instead of “push” but prints 4 normally.
It also gives these warnings on compile:
stack.c: In function ‘shell’:
stack.c:60: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char **’
stack.c: In function ‘main’:
stack.c:71: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char **’
stack.c:65: warning: unused variable ‘cmds’
stack.c:69: warning: ‘arg’ is used uninitialized in this function
Can someone please explain?
When you use the
%sformat specifier, it expect a value which is a pointer to the start of a string. In C, this type ischar *.Taking your
mainfunction, your variables1is of typechar *. Therefore,s1is a valid parameter toprintf, so this line is valid:Note the absence of an
&in front ofs1. In your code, you used the&, which takes the address ofs1, the result of which will be of typechar **. This is the wrong type, so don’t use the&.The thing is,
printfcan’t actually tell what type its arguments are, since it is a variadic function. It simply uses whatever arguments are there, according to the types specified in the format string.The same thing goes for
scanf, but there is a pitfall: you must make sure that enough memory is allocated to account for the user input, else you will experience a buffer overflow with unpredictable results. Aside from this,printfandscanfare perfectly complementary.Anyhoo, this takes care of the compiler warnings, aside from the unused
cmdsvariable (it’s unnecessary in the provided code). Also, there is the part ofargs– it really should be a variable declared inside ofshell, and not passed as a parameter, since its value is not even used insideshell.Don’t know what’s up with the rest of the code. It’s superfluous considering your
mainfunction only calls onshell.