print const char array by the result of sizeof() - c

#include <stdio.h>
#include <stdlib.h>
int constChars(const char* str) {
int size = sizeof(str)/sizeof(char);
printf("Size is %d.\n", size);
int i = 0;
for (i=0;i<size;i++)
printf("%c ", str[i]);
return 0;
}
int main(void) {
char a[10]={'b','c','d','e','f','f','f','f','f','f'};
constChars(a);
return 0;
}
I wrote piece of code like above, but the output result is:
Size is 8.
b c d e f f f f
I'm quite confused, why the sizeof() function gives a size of 8?
I use gcc and freebsd.

When you pass an array to a function, it gets rewritten as a pointer, where sizeof information is lost. If you did this in main instead, i.e:
char a[10]={'b','c','d','e','f','f','f','f','f','f'};
int size = sizeof(a)/sizeof(a[0]);
printf("Size is %d.\n", size);
It prints 10 as expected. But once you pass it to constChars, it prints the size of a pointer.

Str is a pointer to a char. That is typically 4 to 8 bytes. You are not getting the size of the array, but the size of the variable. The only way to know the length of the array is to pass the size in with it, or you could deliminate the array with some sort of signal value (like \0) and do some iteration.

Related

how to find length of an unsigned char pointer in C?

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.

Memcpy from a double pointer in c

I have a pointer A, which is passed into a function with address, say myfunc(&A).
In the function myfunc(char **A) {
I want to copy memory from A[2 to n] to C[2 to n] }
I tried memcpy(&c[2], &(*A)[2], 20);
I am getting the address copied into c rather than the actual info in A.
To copy memory from A[2 to n] to C[2 to n] (from question)
A is a char **, it points to a number of char *.
The 3rd char * is A[2]. You want to use the address of that element in memcpy.
So the line should be
memcpy(&c[2], &A[2], N);
where N is, according to your text, (n-2+1)*sizeof(char *). memcpy size argument ignores the type of what it copies, therefore the total size of what to be copied is to be provided. You want to copy from 2 to n, that makes n-2+1 elements. Each element is a char * which size is sizeof(char *).
-- following comment --
While not clear from the question, if you want to dereference A twice, you copy characters... like
memcpy(&c[2], &A[0][2], 20 /* 20 chars */);
C would be a char *.
memcpy(c+2, *A+2, 20) should be enough.
Here is a test program:
#include <stdio.h>
#include <string.h>
char c[10] = { 'a', 'b' };
void myfunc(char **A)
{
memcpy(c+2, *A+2, 8);
}
int
main(void)
{
char *A = "ABCDEFIJK";
printf("Before: %s\n", c);
myfunc(&A);
printf("After : %s\n", c);
return 0;
}
Run:
$ ./a.out
Before: ab
After : abCDEFIJK

How to know size of an array after passing it to a function [duplicate]

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...

Does sizeof(var) always work in C?

Whenever I want to read or write into a binary file using C, I do use the fread() and fwrite() functions. They need as a parameter the bytes of the datum that is being read or written so I use the sizeof() function. Now the question is:
The books says that I should declare a function like this:
fread(&variable,sizeof(TYPE_OF_VAR),quantity,file);
I've use the following statement which works most of the time but not always:
fread(&variable,sizeof(VARIABLE),quantity,file);
Why does it works sometimes but sometimes it doesn't?
Does it depends on the type of the variable (int, char, etc)?
Does it depends on the quantity of the datum that I use?
The thing to keep in mind is that sizeof is based on what the compiler knows about the type at compile time (ignoring VLA's for now). If you give it a variable, it will use the type of that variable.
So, the only time I can think of where it wouldn't work as you expect is with pointers.
basically what it boils down to is this:
int x[5];
int *y = &x[0];
int *p = malloc(sizeof(int) * 5);
sizeof(x); // == sizeof(int) * 5
sizeof(y); // == sizeof(int *)
sizeof(p); // == sizeof(int *)
This gets tricky when dealing with functions because arrays decay to pointers when passed to a function. Also note that all 3 of these are exactly equivalent:
int func(int *p);
int func(int p[5]);
int func(int p[]);
in all 3, p is a pointer, not an array.
See this Stack Overflow question for a discussion of heap vs. stack: What and where are the stack and heap.
sizeof() on heap elements, like pointers, will return the size of the pointer, not the number of elements that the pointer can store.
However, sizeof() on stack elements: arrays or const char * will return the length of the array or string.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LENGTH 100
int main(int argc, char *argv[])
{
char *a = NULL;
char b[10] = "abcdefghi";
printf("sizeof(b): %zu\n", sizeof(b));
a = malloc(LENGTH + 1);
if (a) {
*(a + LENGTH) = '\0';
memset(a, ' ', LENGTH);
fprintf(stdout, "a (before memcpy):\t[%s]\n", a);
printf("sizeof(a), before: %zu\n", sizeof(a));
memcpy(a, b, sizeof(b) - 1);
fprintf(stdout, "a (after memcpy):\t[%s]\n", a);
printf("sizeof(a), after: %zu\n", sizeof(a));
free(a);
}
return EXIT_SUCCESS;
}
To compile:
$ gcc -Wall sizeofTest.c -o sizeofTest
Output:
$ ./sizeofTest
sizeof(b): 10
a (before memcpy): [ ]
sizeof(a), before: 8
a (after memcpy): [abcdefghi ]
sizeof(a), after: 8
On my platform, a char * points to a memory address that takes up eight bytes.
It will always work.
int main()
{
char a[10];
int b[10];
printf("%d %d %d %d %d %d",sizeof(char),sizeof(int), sizeof(a),sizeof(b), sizeof(a[0]), sizeof(b[0]) );
}
Try the above code. You should see (depending on compiler, mine has char as 1byte and integer as 4 bytes) 1,4,10,40,1,4
It is not different for fread or fwrite or wherever you use it.

Incrementing C pointers

I thought that if a c pointer pointing to a char array was incremented then it would point to the next element in that array. But when I tried this I found that I had to increment it twice. Trying the increment using sizeof(char) I found that adding the size of a char was too much so it had to be divided by two.
#include <stdio.h>
int main(int argc, char * argv[]){
char *pi;
int i;
pi = argv[1];
printf("%d args.\n",argc-1);
printf("input: ");
for(i=0;i<argc-1;i++){
printf("%c, ",*pi);
/*The line below increments pi by 1 char worth of bytes */
//pi+=sizeof(pi)/2;
/* An alternative to the above line is putting pi++ twice - why? */
pi++;
pi++;
}
printf("\n");
return 0;
}
Am I doing something wrong? or am I misunderstanding the method of incrementing pointers?
sizeof(char) is guaranteed to be 1, but sizeof(char*) isn't.
Nevertheless, your function only works by accident.
For example, try calling it with the following parameters:
abc defg
This will yield:
2 args.
input: a, c,
which is plain wrong. The problem is you are incrementing a pointer to the element 1 of argv instead of a pointer to argv.
Try this:
#include <stdio.h>
int main(int argc, char * argv[]){
char **pi;
int i;
pi = argv + 1;
printf("%d args.\n",argc-1);
printf("input: ");
for(i=0;i<argc-1;i++){
printf("%c, ",**pi);
pi++;
}
printf("\n");
return 0;
}
This will print the first character of every argument:
2 args.
input: a, d,
If you have a pointer ptr of type T* and you add N, then the pointer will be advanced by N * sizeof (*ptr) or equivalent N * sizeof (T) bytes. You simply forgot to dereference pi. So what you got with sizeof (pi) was the sizeof of the char*, but not the sizeof of a char. Your line was equivalent to pi+=sizeof(char*)/2; Pointers on your platform are 4 bytes big. Thus in effect you did pi+=2;. Write pi+=2 if you want to increment 2 times. Note that char has an sizeof of 1 by definition. You don't need to do sizeof (char), it is always 1.
sizeof(pi) is returning the size of (char*), which is the type of pi (a pointer, probably two, four, or eight bytes). sizeof(char) will return 1.
However, another thing to understand is that whenever you increment a pointer by a number (e.g.: pi += sizeof(char); pi++; etc.) you are incrementing the pointer by the base size anyways. So:
int *ipointer = &int_array[0];
ipointer += 2;
will actually increment ipointer by 2 times sizeof int.
Another thing you seem to be doing wrong is pointing pi at the first argument, and then looping through all the arguments. If you want to loop through the arguments, try something like this:
for (i = 1; i < argc; i++) {
pi = argv[i];
// ... do something with pi
}

Resources