Simple pointer issue

Go To Last Post
17 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I removed a bunch of code so you guys can see the pertinent stuff. When cs returns, it should be 0x06, but it always returns 0x02. I'm sure it has something to do with passing to the CalcChecksum function. Any ideas?

Thanks,
Chris

int main(void)
{
	char cs = 0;

	char cmd[] = {0x08,0x22,0x00,0x00,0x00,0x01};

	while(1)
	{
		cs = CalcChecksum(cmd);	
	}
}

char CalcChecksum(char* cmd)
{
	return sizeof(cmd);
}

Chief Tinkerer

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Nothing wrong there. The size of the pointer is 2. Sizeof on an array will NOT give the number of elements in an array.

EDIT: I expressed myself rather sloppy. Let's try this: Using sizeof on a pointer (to an array) will not give the number of elements in the array.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Last Edited: Fri. Feb 24, 2012 - 07:19 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
Nothing wrong there. The size of the pointer is 2. Sizeof on an array will NOT give the number of elements in an array.

I see. So I need to pass the function an extra size argument?

Chief Tinkerer

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
Nothing wrong there. The size of the pointer is 2. Sizeof on an array will NOT give the number of elements in an array.

Why not?
Let str be

char str[] = "abcd!"

Then, sizeof( str ) should return 6 (6 is clearly coincidence). In the same way we pass size of arrays in such functions as memcmp, memcpy and so on... Maybe I didn't understand the main point?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

triden wrote:
I see. So I need to pass the function an extra size argument?

In this case I suppose so. I would :)
As far as I can understand you need the size of the array, don't you? Is size a variable? If it isn't there is no problem. If it is, maybe there is some sign of end of the array? For example, check sum?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If

ch=sizeof(cmd);

is executed in main, it in fact returns 6, the length of the array.
However, when it is executed in the function to which the array
is passed, as Johan has stated, it gives the length of the pointer Ie. 2
The function just creates another pointer which will have the pointer to cmd assigned to it, but any reference to array is non-existent.

Declaring the array globally and obviating the parameter passing to the function returns 6

char cmd[] = {0x08,0x22,0x00,0x00,0x00,0x01}; 

 
 char CalcChecksum() 
 { 
    return sizeof(cmd); 
 }



int main(void) 
 { 
    int cs = 0;
    while(1) 
    { 	    
        cs = CalcChecksum();
    } 
 } 

Just declaring the array globally & attempting to pass the pointer still yields 2, the size of the pointer!
Trap for beginners!

Charles Darwin, Lord Kelvin & Murphy are always lurking about!
Lee -.-
Riddle me this...How did the serpent move around before the fall?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Maybe I didn't understand the main point?
But Christan didn't take the size of an array, he took the size of a pointer. The fact that the pointer pointed to an array is irrelevant.
Quote:
is executed in main
No it isn't, it is executed by the compiler, not the program.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Not a bad idea to make it as general as possible, to work with different types of arrays :

char CalcChecksum(void)
{
   return sizeof( cmd ) / sizeof(cmd[0]);
}

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You have three options:

1) Pass the array and as a separate parameter the number of element you want to handle. (Variants are e.g. passing both as members of a struct).

2) If possible, use a terminator element (in much the same way that strings use NULL to terminate a string.

3) Have the number of elements fixed at compile time (and have a #define for that number).

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I stated

Quote:
is executed in main

Koschi replied
Quote:
No it isn't, it is executed by the compiler, not the program.

I never stated that it is run by the program?
I totally disagree that it is executed by the compiler though.
I can't see anything wrong with "saying" that the code associated with that line runs inside main.
Am I missing something? I am quite willing to learn if I am wrong!

Perhaps if you tells us what you were trying to do Chris!

Also, I suspect that sizeof() returns an int and it is bad practice to just assign it to a char. Sooner or later it will prang up on you.

Charles Darwin, Lord Kelvin & Murphy are always lurking about!
Lee -.-
Riddle me this...How did the serpent move around before the fall?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I totally disagree that it is executed by the compiler though.

Lee,

I'm sorry but I don't agree. sizeof() would never lead to any code being generated to run on the target CPU. It is always evaluated on the host during the compilation process.

I was going to say as an example that if you wrote

int main(void) {
 a = b  + c;
} 

then that is code that would "run in main" but actually (certainly in the case of GCC's aggressive optimiser) that line could quite easily be evaluated at compile time and not generate any run time code *if* the values of 'b' and 'c' were known at compile time.

But I think the point is that for most "run in main" would be interpreted as code that executes on the target when main() is entered.

I was going to say that sizeof() might be better understood if you thought of it as a pre-processing operation - but actually that would be misleading - it's a compile time operator. I suppose you could look at it like the << in

(1 << 5)

that << does not generate AVR code to do a left-shift. Instead, at compile time, this expression is replaced by 32.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Point taken! Learned something!

Charles Darwin, Lord Kelvin & Murphy are always lurking about!
Lee -.-
Riddle me this...How did the serpent move around before the fall?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

LDEVRIES wrote:

Also, I suspect that sizeof() returns an int and it is bad practice to just assign it to a char. Sooner or later it will prang up on you.

No, no :) It always returns a char :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I disagree with you haker_fox.

In general, the type "returned" by the sizeof()-operator is size_t, and it is left to the compiler implementor to decide the actual type/size of this. I'll leave it to you to dig into the avrlibc documentation etc and come up with a more correct answer to this.

One thing is for sure: size_t is not 8 bits in avr-gcc, since the largest value sizeof() can "return" is 0x7fff.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
E:\avr[i386_vc]>avr-gcc -mmcu=atmega16 -E -dM test.c | grep SIZE_T
#define __SIZE_T
#define _SIZE_T_DEFINED_
#define _BSD_SIZE_T_DEFINED_
#define _SIZE_T_DEFINED
#define __SIZEOF_SIZE_T__ 2
#define _SYS_SIZE_T_H
#define __SIZE_T__
#define _BSD_SIZE_T_
#define __SIZE_TYPE__ unsigned int
#define _SIZE_T_DECLARED
#define _SIZE_T_
#define _SIZE_T
#define _GCC_SIZE_T

Quod erat demonstradum ;-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

Quod erat demonstradum ;-)

demonstrandum ;-)

Thanks for all the insight everyone. It's great to see a good discussion every once in a while as it makes it really clear where I went wrong :P

My array lengths are always going to be the same size element wise, so I just passed an extra size argument to the function. That way I can still use pointer notation and it knows when the end of the array is. I considered using a sentinel character at the end of the array (like '\n'), but the array elements could be any character which may cause big problems.

This is how I wrote the function:

char CalcChecksum(char* cmd, char size)
{
	int i;
	int cs = 0;

	for(i=0; i

Chris

Chief Tinkerer

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

triden wrote:
My array lengths are always going to be the same size element wise, so I just passed an extra size argument to the function.

Dear Chris, you have a constant length of the array. So why do you need an extra size argument? It takes an extra place in the stack when you call the function. Just use a macro. For example

char cmd[] = {0x08,0x22,0x00,0x00,0x00,0x01};
#define CMD_SIZE sizeof( cmd )

and rebuild the function in such way

char CalcChecksum( char* cmd ) 
{ 
   int i; 
   int cs = 0; 

   for(i=0; i< CMD_SIZE; i++) 
   { 
      cs += *(cmd + i); 
   } 

   cs = (~cs + 1) & 0xFF; 

   return cs; 
}