This question already has answers here:
Length of array in function argument
(9 answers)
Closed 6 years ago.
Let's provide an example. I have one main file:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "otherfile.h"
char output[1024*10];
int main(){
writeSomething(output);
return 0;
}
and another file with the function:
void writeSomething(char *o){
printf("sizeof(o)=%d", sizeof(o));
//code
memset(o,0,sizeof(o));
// code
}
While compiling this, I got the warning:
argument to 'sizeof' in 'memset' call is the same expression as the
destination; did you mean to provide an explicit length?
What I want is to set the whole output array to 0 in my function, so all 1024*10 bytes. But because I pass it as a pointer, it will only set the first 8 characters to 0 (because sizeof(o)=8).
How can I memset the whole array trough a pointer? Is that even possible?
The problem is that when passed as the argument to the function, the array decays into a pointer and information about its size gets lost.
Redefine the function to
void writeSomething(char *o, size_t sz){
printf("sizeof(o)=%d", sizeof(char) * sz);
//code
memset(o, 0, sizeof(char) * sz);
// code
}
so that the call to it looks like writeSomething(output, 1024*10);.
As pointed out in the comments, the C99 standard requires that sizeof(char) be 1, so it's fine to omit the sizeof(char) in the code I provided. However, I prefer to leave it there for stylistic reasons.
Related
This question already has answers here:
How to find the size of a variable without using sizeof
(12 answers)
Closed 2 years ago.
I want to implement a custom function similar to sizeof operator in C . As shown in below code I have a function which is returning size for int datatype.
How can I convert this function into generalize way so it can accept any datatype and return size for passed data type.
#include<stdio.h>
int sizeof_fun(int a)
{
return (char *)(&a+1) - (char *)(&a);
}
int main()
{
int test;
printf("Sizeof int -> %d \n", sizeof_fun(test));
return 0;
}
You cannot do this as a C function.
C function parameters are fixed, and thus you can't have a that dynamically returns different sizes based on the type of parameter. Once inside the function, you don't know the type of the original variable holding the parameter. You would need to either use:
The real sizeof (why do you need to reimplement that? you can't!)
Preprocessor macros
C++ generics/templates
Function overloading (again, C++)
This question already has answers here:
(Why) is using an uninitialized variable undefined behavior?
(7 answers)
Closed 6 years ago.
I want want to read a character string, over the stdin, so I have chosen fgets. But I got this warning: initialization makes integer from pointer without a cast.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#define MAX_LINIA 301
int main(int argc,char *argv[]){
char *buffer;
printf("Enter the input\n");
if (fgets(buffer,MAX_LINIA-1,stdin)==NULL) printf("Error")
else printf("%s", buffer);
return 0:
}
You are using buffer without initialising it, which causes undefined behaviour.
You don't need to use pointer, and can use char array instead (given the max size already defined):
char buffer[MAX_LINIA];
The fgets then be better written as:
if(fgets(buffer,sizeof(buffer),stdin)==NULL)
This question already has answers here:
Message "warning: implicit declaration of function"
(10 answers)
Closed 6 years ago.
I have this very simple code written in C. They are in two separate files.
myFunction.c
#include <stdlib.h>
int *extFunc() {
int *a = (int *) calloc( 1, sizeof(int) );
*a = 12;
return a;
}
main.c
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p = (int *) extFunc();
int x = *p; // causes segmentation fault !
printf("%d\n", *p); // causes segmentation fault !
}
I compiled it with this command cc myFunction.c main.c and the output is like below
main.c:6:19: warning: implicit declaration of function 'extFunc' is invalid in C99 [-Wimplicit-function-declaration]
int *p = (int *) extFunc();
^
main.c:6:11: warning: cast to 'int *' from smaller integer type 'int' [-Wint-to-pointer-cast]
int *p = (int *) extFunc();
^
2 warnings generated.
and when I run it, it gives Segmentation fault: 11. What am I doing wrong?
I checked the function when it is in the main.c file and it worked. However, I need them to be separate like above.
In my original code there are struct pointers instead of integer pointers. I explained my problem here with a simplified example.
You haven't provided a prototype for extFunc(). Create a header file with:
int *extFunc(void);
and include it in both source files.
Since the compiler can't see a prototype it assumed int as return type for extFunc() which probably truncates the address returned by calloc() on your system (probably 64bit system).
But there's no implicit int rule since C99. Always include prototypes for functions and pay attention to compiler warnings.
The warnings are very important here. Especially the one saying
cast to 'int *' from smaller integer type 'int'
What is happening is that the compiler makes an implicit declaration of the function. One that doesn't return int * but int. On certain platform (most notably 64-bit systems) those are not the same which means the pointer p in your main function is not correct. Dereferencing it will lead to undefined behavior.
You need to add a declaration of your function for it to work:
int *extFunc(void);
int main(void) { ... }
Also note that I have changed the argument type for both your extFunc and for main. This is because in C when you don't explicitly say that a function takes void as argument then it can take any number of unspecified arguments.
Compiling both files is not enough, you need to create a header:
/* myFunction.h */
int *extFunc();
And then, include it in your main file:
#include <stdio.h>
#include <stdlib.h>
#include "myFunction.h" /* here */
int main()
{
...
}
The main cannot see the declaration of the function extFunc, so it's return type default to int.
As types int and int* are not of the same size, the function returns an invalid pointer, which when dereferenced caused a segmentation fault.
You will need to create a header called myFunction.h, which will contain the declaration of the function:
int* extFunc( void );
Include this header in main and also change the definition of extFunc to take no arguments in myFunction.c.
This question already has answers here:
what does it mean to convert int to void* or vice versa?
(6 answers)
Closed 9 years ago.
#include <stdio.h>
void pass(void* );
int main()
{
int x;
x = 10;
pass((void*)x);
return 0;
}
void pass(void* x)
{
int y = (int)x;
printf("%d\n", y);
}
output: 10
my questions from the above code..
what happens when we typecast normal variable to void* or any pointer variable?
We have to pass address of the variable to the function because in function definition argument is pointer variable. But this code pass the normal variable ..
This format is followed in linux pthread programming... I am an entry level C programmer. I am compiling this program in linux gcc compiler..
I'm only guessing here, but I think what you are supposed to do is actually pass the address of the variable to the function. You use the address-of operator & to do that
int x = 10;
void *pointer = &x;
And in the function you get the value of the pointer by using the dereference operator *:
int y = *((int *) pointer);
Please read why glib provide macros for this kind of conversions, there's no need to repeat the text here. The main point is: a pointer has a platform dependent size.
If you are planning to use pthreads and you are planning to pass the pass function to pthread_create, you have to malloc/free the arguments you are planning to use (even if the threaded function just need a single int).
Using an integer address (like &x) is probably wrong, indeed each modification you will execute on x will affect the pass behaviour.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
length of array in function argument
Is there any method like the Java can .length from a C point array? Thank you.
No, given a C pointer you cannot determine it's length in a platform agnostic manner.
For an actual C array though see dirkgently's answer
You could get it using a macro:
#define sizeofa(array) sizeof array / sizeof array[ 0 ]
if and only if the array is automatic and you access it in the scope of its definition as:
#include <stdio.h>
int main() {
int x[] = { 1, 2, 3 };
printf("%zd\n", sizeofa( x ));
return 0;
}
However, if you only have a (decayed) pointer you cannot get the array length without resorting to some non-portable implementation specific hack.
If you use MSVC/MinGW there is a NONPORTABLE solution for a real C-pointer:
#include <malloc.h>
char *s=malloc(1234);
#ifdef __int64
printf( "%lu\n", _msize(s));
#else
#endif
For a real C-Array like
AnyType myarray[] = {...};
or
AnyType myarray[constVal];
see the other answer.