Regarding passing pointers as arguments - c

I am trying to code a basic zero threshold function. such that if the value of the array element is greater than zero must remain same else it must be zero. But my problem is with passing the array values from main to the function using pointers. Here's the snippet. im is the input array and im2 is the array to store result. t is the threshold which is 0 and m is the order. On passing the input array from main to thresh function. I just checked the values of im in thresh function but all were showing 0, as commented in code below, instead of original values. where am i going wrong??
int thresh(double *im[], double *im2[], int t, int m)
{
int i, j;
printf("im:%f", im[0]); //here i am getting output as zero instead of 1
for (i = 0; i < m; i++)
{
if (im[i] > t)
im2[i] = im[i];
else
im2[i] = 0;
}
return 0;
}
int main()
{
float im[4] = { 1,-2,3,-4 };
float im2[4];
int th = 0;
thresh((float*)im, (float*)im2, th, 2);
getch();
return 0;
}

Turn on compiler warnings and read them. They are there to help. This is what I got on compilation:
$ gcc main.c
main.c: In function ‘thresh’:
main.c:10:23: warning: comparison between pointer and integer
if (im[i] > t)
^
main.c: In function ‘main’:
main.c:24:12: warning: passing argument 1 of ‘thresh’ from incompatible pointer type [-Wincompatible-pointer-types]
thresh((float*)im, (float*)im2, th, 2);
^
main.c:4:5: note: expected ‘double **’ but argument is of type ‘float *’
int thresh(double *im[], double *im2[], int t, int m)
^~~~~~
main.c:24:24: warning: passing argument 2 of ‘thresh’ from incompatible pointer type [-Wincompatible-pointer-types]
thresh((float*)im, (float*)im2, th, 2);
^
main.c:4:5: note: expected ‘double **’ but argument is of type ‘float *’
int thresh(double *im[], double *im2[], int t, int m)
^~~~~~
So there is some stuff to fix.
First of, the prototype for thresh should be int thresh(double *im, double *im2, int t, int m) or even better int thresh(const double *im, double *im2, int t, int m)
Second, why are you mixing float and double? Stick to one, and stick to double unless you have a really good reason.

Related

Problem to allocate memory outside the main

As a beginner in C, I learned a fancy way to allocate the memory with struct{} to replace something like ch1Buffer = calloc(u32Size, sizeof *ch1Buffer);and put them outside of the int main{} to boost up the calculation speed.
However, I got an error on my variable x saying: This declaration has no storage class or type specifier, you can see the annotation on the side of the code. Should I declared the variable x or?
Here is my example code:
#include <stdio.h>
// New way for memory allocation
struct {
float ch1Buffer;
double ch2Buffer;
double ch2newBuffer;
} *x;
x = calloc(10, sizeof * x); // The error happened on the left side "x": This declaration has no storage class or type specifier
int main()
{
int i,n;
const int u32Size = 10;
float* ch1Buffer = NULL;
double* ch2Buffer = NULL;
double* ch2newBuffer=NULL;
int pBuffer[] = { 10,2,10,2,10,5,10,5,10,2 };
int* pi16Buffer = pBuffer;
// Old way for memory allocation
//ch1Buffer = (float*)calloc(u32Size, sizeof* ch1Buffer);
//ch2Buffer = (double*)calloc(u32Size, sizeof* ch2Buffer);
//ch2newBuffer = (double*)calloc(u32Size, sizeof * ch2Buffer);
// De-interveal the data to ch1Buffer and ch2Buffer
for (i = 0; i < u32Size/2; i++)
{
ch1Buffer[i] += pi16Buffer[i * 2];
ch2Buffer[i] += pi16Buffer[i * 2 + 1];
}
// Use memcpy to pick out the data we are interested
memcpy(ch2newBuffer, &ch2Buffer[2], 2 * sizeof(ch2Buffer[0]));
for (i = 0; i < 2; i++)
{
printf("a[%d] = %f\n", i, *ch2newBuffer);
ch2newBuffer++;
}
free(ch1Buffer);
free(ch2Buffer);
return 0;
}
You can't do a malloc or calloc outside main or any other function. You can declare it at the beginning of your code if you need it as a global variable but you'll need to allocate the memory inside the main for example.
typedef struct mystruct {
float ch1Buffer;
double ch2Buffer;
double ch2newBuffer;
}mystruct;
mystruct* x;
int main (void) {
x = calloc(10, sizeof(mystruct)); // array of your structs
if (!x) { // always check calloc return value
perror("calloc");
exit(EXIT_FAILURE);
}
/* do stuff */
return 0;
}
Also I would suggest giving self-explanatory names to your structs for a better understanding of what it represents.
This gives you a example to use components of each members. Similar to the above anwers, the pointer is defined as a global, and allocated in main(). This Not a good pratice, just for demo.
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
struct xxx {
float f1;
double d2;
double d3;
};
typedef struct xxx mytype;
mytype *x;
void print_mytype()
{
int i;
for (i=0; i<SIZE; i++) printf("x[%d] = %f, %lf, %lf\n", i, x[i].f1, x[i].d2, x[i].d3);
return;
}
void setdata()
{
int i;
for (i=0; i<SIZE; i++)
{
x[i].f1 = rand()/(float)RAND_MAX;
x[i].d2 = rand()/(double)RAND_MAX;
x[i].d3 = rand()/(double)RAND_MAX;
}
}
int main()
{
x = calloc(SIZE, sizeof(mytype));
setdata();
print_mytype();
free(x);
return 0;
}
the posted code does not compile!
Here is what the compiler says about the code:
gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled1.c" -o "untitled1.o"
untitled1.c:9:1: warning: data definition has no type or storage class
9 | x = calloc(10, sizeof * x); // The error happened on the left side "x": This declaration has no storage class or type specifier
| ^
untitled1.c:9:1: warning: type defaults to ‘int’ in declaration of ‘x’ [-Wimplicit-int]
untitled1.c:9:1: error: conflicting types for ‘x’
untitled1.c:8:4: note: previous declaration of ‘x’ was here
8 | } *x;
| ^
untitled1.c:9:5: warning: implicit declaration of function ‘calloc’ [-Wimplicit-function-declaration]
9 | x = calloc(10, sizeof * x); // The error happened on the left side "x": This declaration has no storage class or type specifier
| ^~~~~~
untitled1.c:9:5: warning: incompatible implicit declaration of built-in function ‘calloc’
untitled1.c:2:1: note: include ‘<stdlib.h>’ or provide a declaration of ‘calloc’
1 | #include <stdio.h>
+++ |+#include <stdlib.h>
2 |
untitled1.c:9:23: error: invalid type argument of unary ‘*’ (have ‘int’)
9 | x = calloc(10, sizeof * x); // The error happened on the left side "x": This declaration has no storage class or type specifier
| ^~~
untitled1.c: In function ‘main’:
untitled1.c:33:22: warning: conversion from ‘int’ to ‘float’ may change value [-Wconversion]
33 | ch1Buffer[i] += pi16Buffer[i * 2];
| ^~
untitled1.c:38:5: warning: implicit declaration of function ‘memcpy’ [-Wimplicit-function-declaration]
38 | memcpy(ch2newBuffer, &ch2Buffer[2], 2 * sizeof(ch2Buffer[0]));
| ^~~~~~
untitled1.c:38:5: warning: incompatible implicit declaration of built-in function ‘memcpy’
untitled1.c:2:1: note: include ‘<string.h>’ or provide a declaration of ‘memcpy’
1 | #include <stdio.h>
+++ |+#include <string.h>
2 |
untitled1.c:47:5: warning: implicit declaration of function ‘free’ [-Wimplicit-function-declaration]
47 | free(ch1Buffer);
| ^~~~
untitled1.c:47:5: warning: incompatible implicit declaration of built-in function ‘free’
untitled1.c:47:5: note: include ‘<stdlib.h>’ or provide a declaration of ‘free’
untitled1.c:13:11: warning: unused variable ‘n’ [-Wunused-variable]
13 | int i,n;
| ^
Compilation failed.
Suggest you fix those problems in the code, that you can, before asking us about any problems that you cannot fix.
As the error messages say:
add the statement:
#include <stdlib.h>
add the statement:
#include <string.h>
We are unlikely to help you when the code you post clearly indicates that you have not put any effort into solving the problem(s) your self.

Function with bidimensional array as parameter

I read that to declare a function with a bidimensional array as parameter, I need to specify the number of columns of the array, but if I don't know the size of the matrix I need to use double pointer. However, I can't understand this process very well, can someone give me some short and simple example of this type of function?
Thank you
Also, I tried to write a program but it gives me some warning.
#include<stdio.h>
int diagonal(int**,int );--->first note
int main(){
int N;
scanf("%d",&N);
int array[N][N];
int i;
int j;
printf("Insert the numbers:\n");
for(i=0;i<N;i++){
for(j=0;j<N;j++){
scanf("%d",&array[i][i]);
}
}
diagonal(&array[N][N],N); ---->second warning
}
int diagonal(int**A,int N){
int i;
int condition=0;
for(i=0;i<N-1;i++){
if(A[0][0]!=A[i+1][i+1]){
return -1;
}else{
condition=1;
}
}
if(condition==1){
int val=A[i][i];
int sum= N*val;
return sum;
}
}
Compiler output:
3|note: expected 'int **' but argument is of type 'int *'|
17|warning: passing argument 1 of 'diagonal' from incompatible pointer type|
||=== Build finished: 0 error(s), 1 warning(s) (0 minute(s), 0 second(s)) ===|
The program should scan a matrix and return the sum of elements on the main diagonal if the elements on the diagonal have the same value
return -1 if not.
If you want to use a variable size array as an argument, you need to specify the size first, then use that parameter as the array size in the array argument:
int diagonal(int N, int A[N][N] );
int main() {
...
diagonal(N, array);
}
int diagonal(int N, int A[N][N]){
...
}
You are passing your array wrong. You should pass array instead of &array[N][N]. When you do &array[N][N] you just get address of [N][N] array's element and pass it, it is invalid address.
diagonal(array, N);
Also, when you do scanf, you, probably wanted to get [i][j] element, but you do [i][i] two times.
scanf("%d", &array[i][j]);
17|warning: passing argument 1 of 'diagonal' from incompatible pointer type|
diagonal(&array[N][N],N); //---->warning
here &array[N][N] is of the type int* but your function definition:
int diagonal(int**,int );
has first argument type as int** so you are sending wrong type as an argument. that's the reason why you are get this warning.

error with running multiple thread with C example

I have found an example of multi thread programming which help to determine the prime numbers for a given integar n.it will also take number of thread as a input from the user.But the problem is when i try to execute it give me some errors which very hard to solve.Can anyone help?I am newbies at coding so any type of help and advice will be greatly appreciated.
#include <stdio.h>
#include <math.h>
#include <pthread.h> // required for threads usage
#define MAX_N 100000000
#define MAX_THREADS 25
int nthreads, n, prime[MAX_N+1], nextbase; // next sieve multiplier to be used
// lock for the shared variable nextbase
pthread_mutex_t nextbaselock = PTHREAD_MUTEX_INITIALIZER;
// ID structs for the threads
pthread_t id[MAX_THREADS];
// "crosses out" all odd multiples of k
void crossout(int k)
{ int i;
for (i = 3; i*k <= n; i += 2) {
prime[i*k] = 0;
}
}
// each thread runs this routine
void *worker(int tn) // tn is the thread number (0,1,...)
{ int lim,base,
work = 0; // amount of work done by this thread
// no need to check multipliers bigger than sqrt(n)
lim = sqrt(n);
do {
pthread_mutex_lock(&nextbaselock);
base = nextbase;
nextbase += 2;
// unlock the lock
pthread_mutex_unlock(&nextbaselock);
if (base <= lim) {
// don't bother crossing out if base known composite
if (prime[base]) {
crossout(base);
work++; // log work done by this thread
}
}
else return work;
} while (1);
}
main(int argc, char **argv)
{ int nprimes, // number of primes found
i,work;
n = atoi(argv[1]);
nthreads = atoi(argv[2]);
for (i = 3; i <= n; i++) {
if (i%2 == 0) prime[i] = 0;
else prime[i] = 1;
}
nextbase = 3;
// get threads started
for (i = 0; i < nthreads; i++) {
pthread_create(&id[i],NULL,worker,i);
}
for (i = 0; i < nthreads; i++) {
pthread_join(id[i],&work);
printf("%d values of base done\n",work);
}
nprimes = 1;
for (i = 3; i <= n; i++)
if (prime[i]) {
nprimes++;
}
printf("the number of primes found was %d\n",nprimes);
}
I have the following error while compiling:
In function ‘worker’:
Primes.c:67:12: warning: return makes pointer from integer without a cast [enabled by default]
else return work;
^
Primes.c: In function ‘main’:
Primes.c:88:7: warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type [enabled by default]
pthread_create(&id[i],NULL,worker,i);
^
In file included from Primes.c:15:0:
/usr/include/pthread.h:244:12: note: expected ‘void * (*)(void *)’ but argument is of type ‘void * (*)(int)’
extern int pthread_create (pthread_t *__restrict __newthread,
^
Primes.c:88:7: warning: passing argument 4 of ‘pthread_create’ makes pointer from integer without a cast [enabled by default]
pthread_create(&id[i],NULL,worker,i);
^
In file included from Primes.c:15:0:
/usr/include/pthread.h:244:12: note: expected ‘void * __restrict__’ but argument is of type ‘int’
using: gcc -c -Wall -Wextra -Wconversion -std=gnu99 %f
where %f is the name of the file being compiled
The compiler output the following messages.
I added some commentary for each message that should point you to how to fix the problem.
compiler warning message:
:28:14: warning: conversion to 'int' from 'double' may alter its' value [-Wconversion]
lim = sqrt(n);
The function: sqrt() returns a 'double' but 'lim' is declared a 'int'
Suggest: cast the returned value to 'int'
lim = (int)sqrt(n);
compiler warning message:
:43:12: warning: return makes pointer from integer without a cast [enbled by default]
else return work;
the return type from the worker() function is void*
always exit the worker() function by:
pthread_exit( &work );
compiler warning message:
:24:18: warning: unused parameter 'tn' [-Wunused-parameter]
means the parameter 'tn' is not used. fix this by inserting in that function the line:
(void)tn;
compiler warning message:
47:1: warning: return type defaults to 'int' [enabled by default]
The signature of the main() function is not correct. without using the environment parameter, (almost never used), there are only 2 valid main() signatures and one optional signature.
use the correct signature for what your program needs.
int main( void )
int main( int argc, char *argv[] )
int main() // optional signature
compiler warning message:
50:4: warning: implicit declaration of function 'atoi' [-Wimplicit-function-declaration]
means the header file: stdlib.h has not been #include'd suggest inserting at top of file:
#include <stdlib.h>
compiler warning message:
61:7: warning: passing argument 3 of 'pthread_create' from incompatible pointer type [enabled by default]
means the third parameter to the function: pthread_create() was not a void pointer. suggest:
pthread_create(&id[i],NULL,worker,(void*)&i);
compiler warning message:
67:7: warning: passing argument 2 of 'pthread_join' from incompatible pointer type [enabled by default]
means the variable 'work' should be declared, in file global space, not in the thread function, as:
void * work;
there are other compiler warning messages output, but the above will eliminate them.
I.E. always start with the first compiler message, fix that, then re-compile. then fix the new first message.
Most of the problems with the syntax of the code could have been avoided by paying attention to the man pages for the system functions that were called in the posted code.
Note: the crossout() functions' logic is not correct. the code needs to start at k+k, continue until k<=n and step by k+=k I.E.
for( int k=i+i; k<(n+1); k+=k )
the code seems to be trying to implement a eratosthenes sieve for prime numbers google for the details.
unless your required to use threads, don't, they will just slow things down due to all the context swapping, etc.
this code logic:
for (i = 3; i <= n; i++)
{
if (i%2 == 0) prime[i] = 0;
else prime[i] = 1;
}
seems to be wrong, for one thing, the array prime[] will be initially all 0 because it is in the file global space. As far as I can tell, that code block is not needed at all.
because the work variable will be in the file global space, suggest an array of
void* work[ nthreads ];
then have the thread function: worker() actually use the passed parameter to select which of the entries in the array to be updating.

incompatible pointer types passing 'char *(char *)' to parameter of type 'VALUE (*)()'

I need to extend my ruby code using C code. I have this function on my c file:
char * generateIt(char *valor) {
struct NESSIEstruct w;
u8 digest[DIGESTBYTES];
int i;
for(i=0; valor[i]!='\0'; ++i);
int sizeo = i;
NESSIEinit(&w);
NESSIEadd((u8*)valor, 8*sizeo, &w);
NESSIEfinalize(&w, digest);
return displayIt(digest, DIGESTBYTES);
}
And to make it available to Ruby, at the same file, I have this:
void
Init_whirlpool(){
rb_mWhirlpool = rb_define_module("Whirlpool");
rb_cClass = rb_define_class_under(rb_mWhirlpool, "Class", rb_cObject);
rb_define_method(rb_cClass, "generate", generateIt, 1);
}
But, when I try do run: make, I get this warning:
MacBook-Pro-de-Patricio:whirlpool psantos$ make compiling whirlpool.c
whirlpool.c:2021:43: warning: incompatible pointer types passing 'char
*(char )' to parameter of type 'VALUE ()()' [-Wincompatible-pointer-types] rb_define_method(rb_cClass,
"generate", generateIt, 1);
^~~~~~~~~~ /Users/psantos/.rvm/rubies/ruby-2.0.0-p598/include/ruby-2.0.0/ruby/ruby.h:1290:48:
note: passing argument to parameter here void
rb_define_method(VALUE,const char*,VALUE(*)(ANYARGS),int);
^ 1 warning generated.
Error image: (to be more clear)
How can I solve this?
rb_define_method() takes a Ruby VALUE type.
void rb_define_method(
VALUE klass,
const char *name,
VALUE (*func)(ANYARGS),
int argc
);
Extending Ruby (from upper left menu)
Ruby objects
github.com/silverhammermba, Ruby C API - VALUE

Incompatible pointer type - Trying to modify array from another function

I have an array:
char gameBoard[6][6];
// Initilize the array
for(int i = 0; i < 6; i++) {
for(int o = 0;o < 6;o++) {
gameBoard[i][o] = ' ';
}
}
Later in my code I have a function I am trying to use that will modify this array:
void placePiece(char piece, char *gameBoard) {
int x = 0;
int y = 0;
gameBoard[posXInArray][posYInArray] = piece;
}
I am calling the function from the same scope as where the gameBoard array is created and initialized.
placePiece('X', gameBoard);
The warning I get doing this:
warning: passing argument 2 of ‘placePiece’ from incompatible pointer type [enabled by default]
placePiece('X', gameBoard);
^
note: expected ‘char *’ but argument is of type ‘char (*)[6]’
void placePiece(char piece, char *gameBoard);
I am confused as to what I am doing wrong? I assumed to modify the array from another function I would pass the pointer so that I could directly modify the array. Is this incorrect? I have also tried &gameBoard in the call with the same warning message. I'm guessing I am doing something silly that is incorrect?
You can't pass the 2-dimensional array to this function
void placePiece(char piece, char *gameBoard)
I think this would work fine for you
void placePiece(char piece, unsigned int size, char gameBoard[size][size])
you can use it this way
placePiesce('X', 6, gameBoard);
or better
placePiesce('X', sizeof(gameBoard) / sizeof(gameBoard[0]), gameBoard);
and since the type of gameBoard[0] is char this will also work
placePiesce('X', sizeof(gameBoard), gameBoard);
because sizeof(gameBoard[0]) == 1 in that case.

Resources