I'm teaching myself C since my uni seems to be obsessed with java, so im writing a stack implementation of type int (ill worry about making it generic later). I came across an error that makes not sense to me, missing ';' before 'type'. As far as i can tell my syntax is right, if it is not please do tell. Anyways here is my code:
stack.h
typedef struct{
int *elements;
int size;
int capacity;
}Stack;
void newStack(Stack *s);
void delStack(Stack *s);
void pushToStack(Stack *s, int value);
int popFromStack(Stack *s);
stack.c
#include "stack.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
void newStack(Stack *s){
s->size = 0;
s->capacity = 4;
s->elements = (int*) malloc(4 * sizeof(int));
assert(s->elements != NULL); // allocation worked?
}
void delStack(Stack *s){
free(s->elements);
}
void pushToStack(Stack *s, int value){
if(s->size == s->capacity){
s->size *= 2;
s->elements = (int *) realloc(s->elements, s->size * sizeof(int));
assert(s->elements !=NULL); //reallocation worked?
}
s->elements[s->size] = value;
s->size++;
}
int popFromStack(Stack *s){
assert(s->size>0);
s->size --;
return s->elements[s->size];
}
int main()
{
Stack s1;
newStack(&s1);
int i;
for(i=0; i<3; i++){
pushToStack(&s1, i);
printf("%d ", i);
}
printf("\n");
for(i=0; i<3; i++){
printf("%d ", popFromStack(&s1));
}
delStack(&s1);
getchar();
return 0;
}
The error occurs in main, on the int i; line, but if i move the line up the error goes away and the program runs flawlessly. I want to know why.
CAUSES ERROR:
newStack(&s1);
int i;
NO ERROR:
int i;
newStack(&s1);
PS: just in case it matters.. im using MS Visual Studio 2010
Visual Studio is stuck in a time loop somewhere before 1998, back when the standard mandated that all declarations should be at the beginning of a block.
This was changed in C99, and MS does say it supports the most popular features. Sadly this is not one of them.
In C you must declare all variables at the beginning of your scope. So you can't declare i after your newStack call.
In C89 declarations are made at the top of the scope and thus before any other function call.
However this restriction was removed in C99.
Related
My code is not working... But another example that is similar to my code is working. How can I fix?
It seems like pthread_join() is internally change integer value like my code. But mine does not work.
Can anybody help me to fix?
#include <stdio.h>
void test(void **temp) {
int foo = 3;
*temp = foo;
}
int main(void) {
int temp;
test((void **)&temp);
printf("%d\n", temp);
return 0;
}
pthread_join example:
#include <pthread.h>
#include <stdlib.h>
void *test(void *data) {
int i;
int a = *(int *)data;
for (i = 0; i < 10; i++) {
printf("%d\n", i * a);
}
}
int main() {
int a = 100;
pthread_t thread_t;
int status;
if (pthread_create(&thread_t, NULL, test, (void *)&a) < 0) {
perror("thread create error:");
exit(0);
}
pthread_join(thread_t, (void **)&status);
printf("Thread End %d\n", status);
return 1;
}
But mine does not work..
This statement:
pthread_join(thread_t, (void **)&status);
assigns to status the return value of your thread function. But your function doesn't return anything, so you get garbage.
To fix this, make your test function return something.
P.S. Please do turn on compiler warnings (-Wall, -Wextra) -- the compiler should have warned you of the bug already.
P.P.S Please do not name your variables like this: thread_t -- the _t stands for type, and thead_t is not a type.
You are trying to make temp into two void pointers (void**) when you actually only have one pointer to the int temp. Just return the pointer value and you can use this in a similar pthread example.
#include <stdio.h>
#include <stdlib.h>
void *test(void *temp) {
int *ptr = (int*)malloc(sizeof(int));
*ptr = 3;
return ptr;
}
int main(int argc, char *argv[]) {
int *temp = (int*)test(nullptr);
printf("%d\n", *temp);
free(temp);
return 0;
}
The code doesn't work in my Xcode compiler. It says *&point expected '('. I really don't know what goes wrong. It should have worked.
#include<stdio.h>
#include<stdlib.h>
void transformCopy(int *point);
void transformTrue(int *&point);
int main(){
int *a,*b,i=0;
transformTrue(a);
transformCopy(b);
for(i=0;i<5;i++) {a[i]=i;}
for(i=0;i<5;i++){printf("%d ",a[i]);}
printf("\n");
for(i=0;i<5;i++) {b[i]=i;}
for(i=0;i<5;i++){printf("%d ",b[i]);}
printf("\n");
return 0;
}
void transformCopy(int *point){
point=(int*)malloc(5*sizeof(int));
}
void transformTrue(int *&point){
point=(int*)malloc(5*sizeof(int));
}
*&point expected '('.
References do not exist in C ( void transformTrue(int *&point) ), this is C++ code, not C
If you want to have the equivalent in C you have to use void transformTrue(int **point) and you have to call transformTrue(&a);
If I change your code to do in C what it is done in C++ (see comments) :
#include<stdio.h>
#include<stdlib.h>
void transformCopy(int *point);
void transformTrue(int ** point); /* ** rather than *& */
int main(){
int *a,*b = 0,i=0;
transformTrue(&a); /* &a rather than just a */
transformCopy(b);
for(i=0;i<5;i++) {a[i]=i;}
for(i=0;i<5;i++){printf("%d ",a[i]);}
printf("\n");
for(i=0;i<5;i++) {b[i]=i;}
for(i=0;i<5;i++){printf("%d ",b[i]);}
printf("\n");
return 0;
}
void transformCopy(int *point){
point=(int*)malloc(5*sizeof(int));
}
void transformTrue(int ** point){ /* ** rather than *& */
*point=(int*)malloc(5*sizeof(int)); /* *point = rather than point = */
}
transformTrue(&a) modifies the value of a, but transformCopy(b); does nothing except locally (and a memory leak) and back in main the value of b is still 0, the program will crash when you will try to write in invalid addresses
one possibility is to change transformCopy like that :
int * transformCopy(){
return (int*)malloc(5*sizeof(int));
}
and of course the call to have b = transformCopy();
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am currently trying to solve a task, which is quite hard for me, a beginner to C, to handle and so i came to this point where I do not know what to do anymore.
My task is to implement polynomials with several functions....
The functions should be clear when you look at the code I think.
My exact problem is that i dont get a compiler error but a Segmentation Fault. I marked where my attempts to debug lead me to. But I have absolutely no clue on what I have to change. I hope someone can help me fix my code.
So here are the three code parts:
Number one: poly.c
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "poly.h"
struct poly_t {
unsigned degree;
int *coeffs;
};
//constructor: heap
poly_t *poly_alloc(unsigned degree){
poly_t *heap_p;
heap_p = malloc(sizeof(*heap_p)+(degree+1)*sizeof(int)); //or malloc(sizeof(*heap_p)*(degree+1)) furthermore not sure if degree or degree +1
}
//free heap
void poly_free(poly_t *p){
int *coeffs = p->coeffs;
free(coeffs);
free(p);
}
void poly_set_coeff(poly_t *p, unsigned deg, int coeff){
p->degree = deg;
p->coeffs += deg;
p->coeffs[deg] = coeff;
//does not work Segmentation Fault not sure what to do
//p->coeffs += deg;
//*p->coeffs = coeff;
printf("%d",*p->coeffs);
}
//different variations
poly_t *poly_linear(poly_t *p, int a1, int a0){
p->degree=1;
*p->coeffs=a1;
p->coeffs++;
*p->coeffs=a0;
p->coeffs--;
}
poly_t *poly_quadratic(poly_t *p, int a2, int a1, int a0){
p->degree=2;
*p->coeffs=a2;
p->coeffs++;
*p->coeffs=a1;
p->coeffs++;
*p->coeffs=a0;
p->coeffs-=2;
}
//evaluate using horner
int poly_eval(poly_t const *p, int x){
int d = p->degree;
int next;
int adr = *p->coeffs;
int *arr = p->coeffs;
int res = arr[d];
for(int i=0; i<=d; i++){
adr+=(d-i);
next = arr[adr];
adr-=(d-i);
res = res*x+next;
}
return res;
}
//constructor : .txt
poly_t *poly_alloc_d(){
//needs to be finished
}
Number Two: main.c
#include <stdlib.h>
#include <stdio.h>
#include "poly.h"
int main(int argc, char** argv){
if(argc<3){
fprintf(stderr, "syntax: %s x coeffs...", argv[0]);
return 1;
}
poly_t *p = poly_alloc(argc-3);
for(int i = 2; i<argc; i++){
int coeff = atoi (argv[i]);
poly_set_coeff(p, i-2, coeff);
}
return 0;//for debugging
int x=atoi(argv[1]);
int y=poly_eval(p,x);
poly_free(p);
printf("%d\n", y);
return 0;
}
And at last my header file:
poly.h
#ifndef POLY_H
#define POLY_H
/* unvollständiger Verbund */
typedef struct poly_t poly_t;
poly_t *poly_alloc(unsigned degree);
void poly_free(poly_t *p);
void poly_set_coeff(poly_t *p, unsigned deg, int coeff);
int poly_eval(poly_t const *p, int x);
#endif /* POLY_H */
I appreciate every help. I hope you can help me sort this out and please be patient with me a newbie to C...
Thanks in advance
You have not allocated or freed memory correctly, and the function didn't even return the pointer! I think you were trying to allocate one block of memory for the struct and the array it contains, but the struct does not contain an array: only a pointer to an array. You have to allocate them separately:
typedef struct {
unsigned degree;
int *coeffs;
} poly_t;
//constructor: heap
poly_t *poly_alloc(unsigned degree){
poly_t *heap_p;
heap_p = malloc(sizeof(*heap_p));
if (heap_p == NULL)
exit (1); // allocation error
heap_p->coeffs = malloc(degree * sizeof(int));
if (heap_p->coeffs == NULL)
exit (1); // allocation error
return heap_p;
}
//free heap
void poly_free(poly_t *p){
free(p->coeffs);
free(p);
}
There are other mistakes too, for example
p->coeffs += deg;
You mustn't play with the allocated memory pointer, you already did it correctly like this
p->coeffs[deg] = coeff;
although you can use an intermediate pointer if you want:
int *ptr = p->coeffs + deg;
*ptr = coeff;
file stack.h
typedef struct
{
void *elems;
int elem_size;
int log_len;
int alloc_len;
void (*free_fn)(void *);
} stack;
void stack_new(stack *s, int elem_size, void (*free_fn)(void *));
void stack_dispose(stack *s);
void stack_push(stack *s, void *value);
void stack_pop(stack *s, void *address);
and the implementation file stack.c
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define assert(condition) if(!condition) printf("assert fail\n");exit(0)
void strfree(void *elem);
int main()
{
stack s;
int i;
char *copy, *top;
const char *friends[] = {"joe", "castiel", "lily"};
stack_new(&s, sizeof(char *), strfree);
for(i=0; i<3; i++)
{
copy = strdup(friends[i]);
stack_push(&s, &cp);
}
for(i=0; i<=3; i++)
{
stack_pop(&s, &top);
printf("%s\n", top);
}
stack_dispose(&s);
return 1;
}
void strfree(void *elem)
{
free(*(char **)elem);
}
void stack_new(stack *s, int elem_size, void (*free_fn)(void *))
{
assert(elem_size > 0);
s->alloc_len = 4;
s->free_fn = free_fn;
s->log_len = 0;
s->elem_size = elem_size;
s->elems = malloc(s->alloc_len * s->elem_size);
assert(s->elems != NULL);
}
void stack_dispose(stack *s)
{
int i;
if(s->free_fn)
{
for(i=0; i<s->log_len; i++)
{
s->free_fn((char *)s->elems + i * s->elem_size);
}
}
free(s->elems);
}
void stack_push(stack *s, void *v)
{
if(s->log_len == s->alloc_len)
{
s->alloc_len *= 2;
s->elems = realloc(s->elems, s->alloc_len*s->elem_size);
assert(s->elems != NULL);
}
memcpy((char *)s->elems+s->log_len*s->elem_size, v, s->elem_size);
s->log_len++;
}
void stack_pop(stack *s, void *address)
{
assert(s->log_len > 0);
void *source = (char *)s->elems + (s->log_len - 1) * s->elem_size;
memcpy(address, source, s->elem_size);
s->log_len--;
}
So it compiles but it doesn't run.
It has a warning about comparison between pointer and integer which comes from the code
assert(s->elems != NULL);
It is broken somewhere, it will not print out the three names defined here
const char *friends[] = {"joe", "castiel", "lily"};
I know the code is bit of too much, but I really wish to get some help, I'm at my wits end here.
One problem is your assert macro:
#define assert(condition) if(!condition) printf("assert fail\n");exit(0)
The exit(0); is executed regardless of whether the condition is true or false (look at the generated code again). If you want assertions, use the standard #include <assert.h>.
Your first identified problem is with:
assert(s->elems != NULL);
Given the definition, this is equivalent to:
if (!s->elems != NULL)
printf("assert fail\n");
exit(0);
The !s->elems is an integer, either 0 or 1, compared with a null pointer constant. Hence the warning. When writing macros, enclose arguments in parentheses. At minimum:
#define assert(condition) if(!(condition)){printf("assert fail\n");exit(1);}
This still isn't a good macro, but at least it will get rid of the first compilation error, and your stack_new() won't exit when it is called just because it is called. Note that it is conventional to exit with a non-zero status when there is a problem — exiting with zero indicates success.
Run your code in a debugger using GDB to see what it is doing line by line. Google "gdb cheat sheet" to get started and compile your code with -g.
Why do I get segmentation fault in this function:
#include <stdio.h>
#include <stdlib.h>
#include "math.h"
vec_t mtrx_multiple (sparse_mat_t a, vec_t c) {
vec_t result;
int i;
result.n = a.n;
printf("result.n: %d\n", result.n);
result.vec = malloc(a.n * sizeof *result.vec);
for(i=0; i<a.n; i++)
result.vec[i] = c.vec[i] * a.a[a.ja[i]];
return result;
}
The structure is:
typedef struct {
int n;
int *vec;
} vec_t;
typedef struct {
int *a;
int *ia;
int *ja;
int n;
} sparse_mat_t;
Thanks for help
I suspect the problem is with a.a[a.ja[i]], you should try verifying the values a.ja[i] before using them to index a.a.
It would be useful to know how a is initialised, and also on which line the segfault occurs.
Malloc could be failing and returning null.
a.ja[i] might not be between 0 and n. What is the ja array supposed to represent, anyway?
Our speculating isn't going to produce the answer. Running your program under a debugger will.
I suspect this is the line where the trouble is:
result.vec = malloc(a.n * sizeof *result.vec);
for(i=0; i<a.n; i++)
result.vec[i] = c.vec[i] * a.a[a.ja[i]];
The reason is that you are not mallocing for each result.vec[i]..
Can you confirm this?
Edit:
Thanks Alok and Devel for informing me about my error...
What does sizeof *result.vec return? Admittedly it looks confusing as if the precedence between sizeof gets mixed with the *...
Hope this helps,
Best regards,
Tom.
typedef struct {
int n;
int *vec;
} vec_t;
int main(int argc, char **argv) {
vec_t result;
int i;
int size;
result.n = 5;
size = result.n * sizeof *result.vec;
result.vec = malloc(size);
for(i=0; i<result.n; i++) {
result.vec[i] = i;
}
return i;
}
I have to agree with Autopulated, this version of your code runs just fine, the only thing I left out in this refactoring is the a and c related stuff. I would check that a and c are being initialized properly.