I want to find size or length of an unsigned char pointer in a function where that pointer is an argument to that function.Near the pointers declaration size is coming correctly.
But when i am trying to find size in function it is giving 4.
How can i do this ?
#include <stdio.h>
//void writeFile(unsigned char *da);
void writeFile(char *da);
int main(int arc,char **argv)
{
unsigned char block_bmp[]=
{
0x0,0xff,0xff,0xff,0x0,0x0,0x0,0xff,0xff,0xff,0x0,0x0,0x0,0xff,0xff,0xff,//*16bytes*
};
printf("size::%d\n",sizeof(block_bmp));
writeFile(block_bmp);
}
//void writeFile(unsigned char *da)
void writeFile(char *da)
{
printf("%d\n",__LINE__);
printf("size::%d\n",sizeof(da));
printf("length::%d\n",strlen(da));
FILE *fp;
int i;
fp=fopen("/tmp/hexfile","wb");
for(i=0;i<3780;i++)
fprintf(fp,"%c",da[i]);
// fwrite(da,sizeof(unsigned char),sizeof(da),fp);
fclose(fp);
}
If it points to a NULL-terminated string, use strlen. If not, the pointer is just some memory address for the called function, without any additional information about the size of the array (I assume, you try to pass an array). I suggest passing the number of array elements as additional parameter to the function.
You can not use sizeof in this condition. You should be using the strlen if the char array is NULL terminated.
When you pass array to a function, it decays to pointer, you can't use sizeof on this pointer to get the size of the array. The sizeof will give you 4 bytes (assuming 32 bit machine).
Example:
#include <stdio.h>
void fun(int myArray[10])
{
int i = sizeof(myArray);
printf("Size of myArray = %d\n", i);
}
int main(void)
{
// Initialize all elements of myArray to 0
int myArray[10] = {0};
fun(myArray);
getch();
return 0;
}
/**************OUTPUT**************
Size of myArray = 4
***********************************/
unsigned char array[100];
// sizeof(array) == 100
unsigned char* ptr = array;
// sizeof(ptr) == 4 for 32 bit platform.
When you call a function such as
foo(unsigned char* ptr)
{
}
with 'array' as argument, you only see a 'unsigned char *', not an array with 100 elements. That's why 'sizeof' returns 4.
pointers size sizeof(any_pointer_variable) will not depend on the datatype to which it is going to point. The size of the pointer is mostly 4 that is what you are getting in function. and it doesnt depend on what it points to. all pointers will have same size independent of what type they point to.
Related
I have this code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
static char** testing(FILE *fp)
{
char temp[255];
char data[255][255];
for (int i = 0; !feof(fp); i++)
{
fgets(temp, 255, fp);
strcpy(data[i], temp);
}
for (int i = 0; i < 66; i++)
{
printf("%s", data[i]);
}
return data;
}
int main(int argc, char const *argv[])
{
FILE *fp;
fp = fopen(argv[1], "r");
testing(fp);
}
I want to return the 2D array data but when I compile this, I get the output:
returning 'char (*)[255]' from a function with incompatible return type 'char **' [-Wincompatible-pointer-types] return data;
I don't see what I've done wrong.
Any help would be very much appreciated.
data is two-dimensional array of chars. When 2D array decals to a pointer it has the type of pointer to the char array.
the function should be declared as :
static char (*testing(FILE *fp))[255]
Returning the pointer to local object is dangerous as dereferencing the returned pointer invokes Undefined Behaviour. The local automatic variables stop existing when a function returns. You need to use (a)global variables, (b)static variables or use (c)malloc family functions to allocate the memory.
(a):
char data[255][255];
static char (*testing(FILE *fp))[255]
{
/* ... */
(b):
static char (*testing(FILE *fp))[255]
{
static char data[255][255];
/* ... */
(c):
static char (*testing(FILE *fp))[255]
{
char (*data)[255] = malloc(255 * sizeof(*data));
/* ... */
Your data variable is not allocated dynamically and therefor cannot be used outside your function. You need to return a pointer to a dynamically allocated array to use it outside of it.
Here for more details about heap and stack:
You declared the return value to be a char** which can be interpreted by reading from right to left, so is a pointer to a pointer of type char. While data is a two dimensional array. Returning data as you do, is returning the pointer to data, which the compiler sees as a pointer to a one-dimensional array. That is why you got an incompatible data error. Additionally you have issue with using a locally declared variable which is not visible outside the function so the value returned would result in a protection fault.
So I've got to do an exercise in C where I have to create an twodimensional array as a "field". We have been given the term typedef char name[300][300]. Now I want to use malloc on this typedef char name, but I can't figure out how (I'm a total beginner in C). I've searched all the way through the internet but couldn't find an example with a typedef char thing and I have no plan how I can do that. Do I have to create a pointer or some special magic to use malloc on this or what am I missing out?
type *p = malloc(sizeof *p); pretty much works generically.
#include <stdio.h>
#include <stdlib.h>
typedef char name[300][300]; //makes `name` a typedef for `char[300][300]`;
int main()
{
name *p = malloc(sizeof *p);
printf("%zu\n", sizeof *p); //verify that this is 300*300==90000 bytes large
}
How to use the typedef char name[300][300] Dynamic memory allocation?
#include<stdio.h>
#include<stdlib.h>
typedef char name[300][300];
int main(){
name *namelist= malloc(sizeof *namelist); // we are pointing to char [300][300]
/* check the return value of malloc */
if( namelist == NULL ){
fprintf(stderr,"%s\n","Error in malloc");
exit(1);
}
for(int i=0;i<5;i++)
scanf("%299s",(*namelist)[i]); // dereferencing it to acccess the 2d array
for(int i=0;i<5;i++)
printf("%s\n",(*namelist)[i]);
free(namelist);
return 0;
}
Here the use of the typdef is shown with a small code.
Explanation:
typedef char name[300][300]
We associate name with the type char [300][300].
Defines name as 300 elements array of 300 element array of type
char.
Now pointer to this is basically pointer to a 2d array char[300][300] or simply char (*)[300][300].
That's why we need to dereference the variable first (*namelist) and then we access the 2d array.
Extra points:
Why sizeof *namelist = 90000 Byte?
Because *namelist denote the 2d array. From standard §6.5.3.4
When sizeof is applied to an operand that has type char, unsigned
char, or signed char, (or a qualified version thereof) the result is
1. When applied to an operand that has array type, the result is the total number of bytes in the array.
So the array has 300 x 300 = 90000 char variables each of which is of 1 Byte. So 90000 byte.
Emphasis added
This is not what you got to work with but you could also wrap char name[300][300] table in your own type:
#include <stdio.h>
#include <stdlib.h>
typedef struct my_array_type { char name[300][300]; } my_array_type;
int main(int argc, char* argv[]){
my_array_type * my_table = malloc(sizeof *my_table);
printf("%zu\n", sizeof *my_table);
return 0;
}
I would like to copy 4 bytes from unsigned int to unsigned char array. Once executed the following function get_result goes to segmentation fault :
int exec_cmd(unsigned int * apu32Var)
{
int ret = -1;
char cmd[100] = { 0 };
char resp[100] = { 0 };
sprintf(cmd, "%s %s", "/home/send_frames.sh", "read");
ret = exec_cmd_ret_result(cmd, resp);
if( apu32Var != NULL )
{
*apu32Var = (((unsigned int)resp[0]) <<24)+(((unsigned int)resp[1]) <<16)+(((unsigned int)resp[2]) <<8)+(unsigned int)resp[3];
}
return ret;
}
int get_result(unsigned char * buffer, unsigned short * size)
{
unsigned int u32Var = 0;
exec_cmd(&u32Var);
memcpy(buffer, &u32Var, sizeof(unsigned int));
*size += sizeof(unsigned int);
return 0;
}
int main(int argc, char **argv)
{
unsigned char *buf;
unsigned short *size;
get_result(buf+4, size);
return 0;
}
However, regarding to memcpy() man page it seems memcpy() are well managed. What is going wrong ?
Assuming your call to test_result actually should be calling get_result, then you have two big problems.
The first and most serious is that you pass in uninitialized local variables as arguments to the function. Uninitialized local variables have indeterminate values. For a pointer, it means it can point just about anywhere, and trying to dereference it will lead to undefined behavior. You need to actually make these pointers point somewhere valid for it to work. This goes for both variables.
The second problem is that you misunderstand how emulating pass by reference works in C. Yes the function should take a pointer, but you should not actually create a pointer variable and pass to the function. Instead you should use the address-of operator & on a non-pointer variable.
To solve both problems, your code should look something like
unsigned char buf[256] = { 0 }; // Arbitrary size, all initialized to zero
unsigned short size = 0; // To make sure it's properly initialized
get_result(buf + 4, &size); // Note use of & to pass a pointer to the variable size
Note that it works using an array, since arrays naturally decays to pointers to its first element.
buf in main is never initialized, so it points to some random location in memory. This is undefined behavior and a perfect recipe for a segfault.
Similarly, *size is read from when you use +=, but the value was never initialized in main, so your dereference an undefined value.
You should declare buf as an array of sufficient size and pass that in. Also, declare size as an int, initialize it to 0, and pass its address:
int main(int argc, char **argv)
{
unsigned char buf[100];
unsigned short size = 0;
// I'm assuming this was a typo and you ment to call get_result instead of test_result
get_result(buf, &size);
return 0;
}
This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 9 years ago.
I have to know size of an array after passing it to a function. For example,
#include<stdio.h>
void func(char *ptr)
{
printf("%d\n",------); //Here i want the actual size of the array passed to ptr. What to fill in the blank to get total size of the arr[]
}
main()
{
char arr[10] = "Hello";
printf("%d\n",sizeof(arr)); // here it is giving 10 bytes that is equal to total size of the array
func(arr);
}
No you can't, the compiler doesn't know that the pointer at the function is pointing to an array, there are some solutions though, I can state:
1) pass the length with the function parameters :
void func(char *ptr, int length)
{
printf("%d\n",length);
}
2) if your array is always of type char, you can put a NULL char ('\0') and the use strlen
#include <stdio.h>
#include <string.h>
void func(char *ptr)
{
printf("%zu\n",strlen(ptr) + 1);
}
int main()
{
char arr[10] = {10,2,11,223,4,45,57,11, 12 ,'\0'};
printf("%zu\n",sizeof(arr));
func(arr);
}
// prints
//10
//10
Cheers
No way. You have to pass the size of array too. When you are passing an array to a function then actually you are passing pointer to its first element. In this case size of array is not known to the function.
Arrays decays into pointers when you pass to a function. With pointer alone, you can not get the size of the array. You have to pass one more argument to the calling function which is the size of the array.
Example:
#include <stdio.h>
void fun(int myArray[10])
{
int i = sizeof(myArray);
printf("Size of myArray = %d\n", i);
}
int main(void)
{
// Initialize all elements of myArray to 0
int myArray[10] = {0};
fun(myArray);
getch();
return 0;
}
Here the output will be 4 (depending on the sizeof pointer on your platform, it may vary)
This is because, “arrays decays into pointers” the compiler pretends that the array parameter was declared as a pointer and hence the size of pointer is printed.
So, you have to pass the size as one more parameter to the calling function...
#include <stdio.h>
void fun(int myArray[10], int size)
{
printf("Size of myArray = %d\n", size);
}
int main(void)
{
// Initialize all elements of myArray to 0
int myArray[10] = {0};
fun(myArray, sizeof(myArray));
getchar(); ^----------------Here you are passing the size
return 0;
}
So, here the output is 40...
I am trying to write a program that will mutliply two numbers, but output the result in binary, showing the calculation (i.e. shifting the rows). I'm storing the binary numbers as an array of 32 characters, and each element is either 1 or 0.
I have a function that will convert decimal to binary character array, but then my array only exists within the function, but I need to use the array within another function and also within main. I was thinking it might be possible to use pointers to change the value of the array in main from within my converter function, so then the array will exist in main and can be used in other functions. Is this possible?
I've declared two pointers to character arrays:
char (*binOne)[32];
char (*binTwo)[32];
if I pass the pointer as a parameter to the function, can I still access each element? Sorry if I'm not making much sense here.
In C, most of the time array behaves like pointer to its first element, so what you probably want to do is:
void foo(char* arr){
//some stuff, for example change 21-th element of array to be x
arr[20] = 'x';
}
int main(){
char binOne[32];
char binTwo[32];
// change array binOne
binOne[20] = 'a';
foo(binOne);
// now binOne[20] = 'x'
foo(binTwo);
// now binTwo[20] = 'x'
}
A continuation of what I added as a comment:
In C, if you want to modify/return an array, you'll do that by passing a pointer to it as an argument. For example:
int toBinary(char *buff, int num) { /* convert the int, return 1 on success */ }
...
char buff[32];
toBinary(buff, 9001);
In C, an array's name is it's address, it's the address of the first element:
buff == &buff == &buff[0]
Yes, this is possible. But you only need a pointer to the array not an array of pointers.
You need to prototype like
e.g.
void int_to_arr(int n, char *arr);
void arr_to_int(int *n, char *arr);
in main(){
char *binarr = calloc(32, sizeof(char));
int n = 42;
int_to_arr(n, binarr);
}
void int_to_arr(int n, char *arr)
{
//do you conversion
//access array with
// arr[i]
}
void arr_to_int(int *n, char *arr)
{
//do you conversion
//access array with
// *n = result;
}