sizeof in function

Pages: 12
i don't know why is this happen...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <conio.h>
using namespace std;

//temporary function for password until i get a better one -_-!
void pwd (char pwrd[]) {
	//btw, have better idea for this?
	for (int i = 0; i < 256; ++i) {
		pwrd [i] = getch();
		if (pwrd [i] == 13) {
			pwrd [i] = '\0';
			break;
		}
		cout << "*";
	}
	cout << endl;
}

void encrypt (char pass[], int encr) {
	//it doesn't loop until the real length of pass
	for (int i = 0; i < sizeof (pass); ++i) {
		if (pass[i] == '\0')
			break;
		pass [i] += encr;
	}
}

void decrypt (char pass [], int decr) {
	//as same as encrypt
	for (int i = 0; i < sizeof (pass); ++i) {
		if (pass [i] == '\0')
			break;
		pass [i] -= decr;
	}
}

int main() {
	char pass [256], yn;
	int en;
	pwd (pass);
	cout << "do you want to encrypt it (y/n): ";
	cin >> yn;
	if (yn == 'y') {
		cout << "how you want to ecnrypt your password (0 - 30000): ";
		cin >> en;
		encrypt (pass, en);
	}
	yn = NULL;
	cout << "your password is: " << pass << endl;
	cout << "do you want to decrypt it (y/n): ";
	cin >> yn;
	if (yn == 'y') {
		decrypt (pass, en);
		cout << "your real password is: " << pass << endl;
	}
	cout << "press any key to continue...";
	getch();
	return 0;
}


when i change the function like this:

1
2
3
void encrypt (char pass[], int encr) {
	cout << sizeof (pass) << endl; //the result is 4!
}


and when i tried in the main():

1
2
3
4
5
6
7
int main() {
	char pass [256], yn;
	int en;
	pwd (pass);
	cout << sizeof (pass) << endl; //the result is 256!
	//...
}


why is that?
because when you pass an array to a function, you don't actually pass the array, you pass a pointer to the first element in the array.

1
2
3
void encrypt (char pass[], int encr) {  //  <- this

void encrypt (char* pass, int encr) { // <- is the same as this 


Since 'pass' here is a pointer, sizeof(pass) gives you the size of a pointer (which in this case is 4).

However in main:

1
2
3
char pass [256], yn;  // <- pass is an array, not a pointer

cout << sizeof(pass);  // <- so this gives you the size of the array 
oh yeah, btw, why if we pass an array into a function, the array treated as pointer / address of its elements? is it because an array is actually a constant pointer? so it's pointed to the address of its elements without explicitly type the ampersand (&)? because i got an error when i write this:

void test (char & pass [])
why if we pass an array into a function, the array treated as pointer / address of its elements?


Because that's the way C (and thus C++) decided to do it. I agree it's rather inconsistent, but it's one of those things you just have to accept.

is it because an array is actually a constant pointer?


No. Technically that's not even true. arrays and pointers have similar syntax, and it might help to think of them in the same way, but they're not the same thing.

This sizeof issue is one example of how they're different.

because i got an error when i write this:

void test (char & pass [])


That's because you're trying to pass an array of char&s (references to chars). Nothing to do with a pointer.

There's no way to pass arrays "by value" to functions in C/C++. The language simply doesn't allow it. You can get around that by putting the array in a structure and passing the structure by value, but that's not really a good idea.
There's no way to pass arrays "by value" to functions in C/C++

do you mean "pass by reference"?
@chipp
nope that's a completely different method.
pass by value means that you have to copy the ENTIRE variable into function.
pass by reference means you just have to copy its address only.

in this case, passing the array by value means you have to copy the array manually.
create another array and then pass it into function (as a reference).

back in the old days, copying into local variable could mean faster execution inside function.
because accessing pointer means extra work.
but nowadays that's not always the case.
it really depends on the hardware and more importantly, your code.

I suggest you try both and loop it for like a million times. :D

btw, it might be a good idea to learn another language like PHP, VB. both support pass by value and reference.
what i'm asking is what disch mean, is it pass by value or reference because he said before:

That's because you're trying to pass an array of char&s (references to chars).

because he's saying that i'm trying to pass a reference, but then he said that you can't pass by value. so i'm asking is he mean "pass by reference" instead of "pass by value"? cause i don't see any attempt to pass it by value
because he's saying that i'm trying to pass a reference, but then he said that you can't pass by value.

Well I get what Disch was trying to say. Because in other languages you can actually do both pass an array by value or reference. So some people might get confused.

But hear me out. Array is a large chunk of data. Imagine if every time you call a function you have to create & copy the exact same array. I mean do we need the whole new data? Why don’t we just use the original one?

So it might be a better idea to pass it by its reference address only.

I see that we have gone off your original sizeof in function topic. I'm sorry if I can't explain it into simpler words.
closed account (zb0S216C)
You can pass an array by reference like this, if anybody wants to know:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
template < typename __Typename__, size_t stSize >
void vArrayFunction( const __Typename__( &rThisArray )[ stSize ] )
{
    for( size_t stLoop( 0 ); stLoop < stSize; stLoop++ )
        std::cout << "Value at " << stLoop << " is: " << rThisArray[ stLoop ] << std::endl;
}

int main( )
{
    // Calling it would appear as:
    int Array[ 3 ] = 
    {
        3, 9, 2
    };

    vArrayFunction( Array );

    std::cin.get( );
    return 0;
}

Wazzak
Last edited on
Huh. That actually does give the callee all the information about the array, but at the cost of creating as many copies of the function as times it is called for different arrays.
closed account (zb0S216C)
It's an example, Helios. I'm not saying he/she should use that function; it's merely a guide on how to pass an array by reference. It doesn't have to be a template, of course.

Wazzak
closed account (z05DSL3A)
Chipp wrote:
why if we pass an array into a function, the array treated as pointer / address of its elements? is it because an array is actually a constant pointer?

When every you use the name of an array in an expression, the name is automatically converted to a pointer to the first element. It does not matter it is a parameter to a function or anywhere else in your code.

It is only syntactic sugar that lets you define a parameter as an array.
Grey Wolf wrote:
When every you use the name of an array in an expression, the name is automatically converted to a pointer to the first element. It does not matter it is a parameter to a function or anywhere else in your code.


Ehhh.....

Disch wrote:
Technically that's not even true. arrays and pointers have similar syntax, and it might help to think of them in the same way, but they're not the same thing.

This sizeof issue is one example of how they're different.



If array names were automatically converted to pointers, then sizeof(arrayname) would give you the size of a pointer, which isn't the case.
closed account (z05DSL3A)
I believe that sizeof() is the exception to the rule, probably because its behavior is specified in the standard.

Edit:
According to the standard (several places) the sizeof operator does not evaluate its operand. Therefore the operand is not being 'used' in the sense of being evaluated.
Last edited on
@relic: maybe you should read disch's post first, and then my replied for that post. i didn't said that i don't understand about "pass by value" or "reference" nor the advantage of using the pass by reference. but what i mean is i want to clarify what's disch mean in this line:


There's no way to pass arrays "by value" to functions in C/C++.


i'm asking does he mean "pass by reference" ? because in the previous line he said:

That's because you're trying to pass an array of char&s (references to chars). Nothing to do with a pointer.


so why did he said, that i can't pass array "by value"? because i didn't... is it a separate explanation, or it is continued explanations from the previous line (2nd quote), is there's something i didn't understand? well, that's what i;m asking...
The conversion only applies when assigning the array to a pointer (including parameter passing). sizeof only extracts the type information that the compiler has on a symbol, it doesn't actually involve the array that the symbol references.
closed account (z05DSL3A)
No he means pass-by-value, the array is not copied into the local variables of a function when you call something like void encrypt (char pass[], int encr). A pointer is passed-by-value instead.

after you wrote
because i got an error when i write this:

void test (char & pass [])

he made a comment on why that failed and then when back to the point in hand.

BTW if you wanted to pass that array (above) by reference you would declare it as
void test (char (& pass) [256])
Last edited on
this "pass by value" and "pass by reference" is confusing because actually, when you said that the pointer is passed by value it is actually mean that the value of the pointer is passed to the function and the value of the pointer is actually the address (reference) of a variable. that's kind of little confusing... :DDD

and, i don't know which is right between you and disch, but for my opinion i said the pointer and the array has a similar behavior (in the way they pointed at the address), but they don't actually the same. they're not the exact the same thing. but, i;m just guessing, dude :D

'bout your example, i'll try it, i wanna do some experiment :D

append: btw, it doesn't said that sizeof () determines which is pointer and which is not, but the way the language directing, make the different result of sizeof()

edit2: i mean disch
Last edited on
btw, can anyone give me an example of size_t?

Pointers and references accomplish the same thing.

you could also write void test (char & pass []) as void test (char * pass )

The following 2 functions will print out the same address when called as follows

1
2
3
4
5
6
7
8
9
10
11
12
13
14
char arr[64];

FuncByRef( arr );
FuncByPtr( arr );

void FuncByRef( char (& n)[64] )
{
  printf( "%p\n", n );
}

void FuncByPtr( char * n )
{
  printf( "%p\n", n );
}


Pages: 12