Need to know the size of the memory block pointed to by a char*

F

Frodo Baggins

Hi
I need to know the size of the memory block pointed to by a char* in a
function receiving this pointer. Typically, this pointer points to a
string. strlen() will not do the job since sometimes the string is not
null terminated.
That is:


int foo(void)
{
/* ...... */
char buf[20];
a(buf);
/* ....... */
return 0;
}
void a(char* ptr)
{
/* Here, I need the length of the mem block pointed at by ptr */
}
 
D

dbtid

Frodo said:
Hi
I need to know the size of the memory block pointed to by a char* in a
function receiving this pointer. Typically, this pointer points to a
string. strlen() will not do the job since sometimes the string is not
null terminated.
That is:


int foo(void)
{
/* ...... */
char buf[20];
a(buf);
/* ....... */
return 0;
}
void a(char* ptr)
{
/* Here, I need the length of the mem block pointed at by ptr */
}

For objects declared as arrays, sizeof(a) will work just fine.

For blocks of memory obtained by using malloc(), you must keep track of
the length yourself. Using sizeof on a pointer only gives you the
number of bytes for the pointer type.
 
C

Chris Dollin

Frodo Baggins wrote:

(Watch out! Records suggest that this year you will have to leave
home, carry a heavy burden, suffer betrayal and loss, eat poorly,
and return to find that life is no longer satisfying. You can
avoid all this, however, if you'll just lend me your ring a moment ...)
I need to know the size of the memory block pointed to by a char* in a
function receiving this pointer.

Pass in the size as a parameter.

Or, use structs with both the size and the pointer, rather than
just char* values.

You can't find out just from the pointer how many items there are.
Typically, this pointer points to a
string. strlen() will not do the job since sometimes the string is not
null terminated.

If it's not nul-terminated, it isn't a C string.
That is:

int foo(void)
{
/* ...... */
char buf[20];
a(buf);
/* ....... */
return 0;
}
void a(char* ptr)
{
/* Here, I need the length of the mem block pointed at by ptr */
}

void a( int length, char *ptr ) ...

.... a( sizeof (buf), buf ) ...
 
R

Richard Heathfield

matevzb said:
No, it will not.

Yes, it will. But the OP can't use sizeof because he's not actually getting
an array, merely a pointer.
Arrays decay into pointers when passed to a function,

And the function thus does not receive an array parameter (not least because
there's no such thing), but a pointer parameter, and so sizeof will yield
not the size of the array in bytes but the size of the pointer in bytes.
so once inside a function, it's too late to get the size information
Right.

(see http://c-faq.com/aryptr/aryptrparam.html for more detail). As
Chris suggested, pass the size as a parameter to the called function.

Right again.
 
M

matevzb

matevzb said:


Yes, it will. But the OP can't use sizeof because he's not actually getting
an array, merely a pointer.
Indeed, that's another way of interpreting "sizeof(a) will work just
fine". What I meant was "no, it will not work as a means of getting
information about array size" (which I presumed dbtid suggested) and
not "sizeof(a) will not work fine", which of course it always should.
 
R

Richard Heathfield

matevzb said:
Indeed, that's another way of interpreting "sizeof(a) will work just
fine". What I meant was "no, it will not work as a means of getting
information about array size" (which I presumed dbtid suggested) and
not "sizeof(a) will not work fine", which of course it always should.

Well, actually you have misinterpreted me, albeit in a way that does not
give rise to any C-ontradictions so it probably doesn't matter. What does
matter (and I think we are in full agreement here) is this:

#include <stddef.h>

void foo(int *p)
{
size_t x = sizeof p; /* gives size of pointer, in bytes, probably 4 */
}

void bar(int *q, size_t nobj)
{
while(nobj--)
{
*q++ = 42;
}
}

int main(void)
{
int arr[20] = {0};
size_t y = sizeof arr; /* gives size of array, in bytes, probably 80 */
foo(arr); /* not good enough */
bar(arr, sizeof arr / sizeof arr[0]); /* good enough */
return 0;
}
 
C

CBFalconer

Frodo said:
I need to know the size of the memory block pointed to by a char*
in a function receiving this pointer. Typically, this pointer
points to a string. strlen() will not do the job since sometimes
the string is not null terminated.

Then it isn't a string. Besides which strlen doesn't give the size
of the storage. Just add a parameter to the function holding the
maxsize available. Don't forget to allow for the '\0' termination
char.

ex: #define MAXSZ 123
...
myfunct(char *s, size_t maxsz) {
/* myfunc code */
}
...
callingfunction(whatever) {
char mystring[2 * MAXSZ];
...
myfunction(&mystring, sizeof(mystring)-1);
...
}
 
M

matevzb

Well, actually you have misinterpreted me, albeit in a way that does not
give rise to any C-ontradictions so it probably doesn't matter.
Most probably, either due to my (non-intentional) ignorance, or the
fact that I've yet to learn all the subtleties of English language. I
possibly misinterpreted dbtid's post too. And all of these are poor
excuses of course =/
What does matter (and I think we are in full agreement here) is this:

#include <stddef.h>

void foo(int *p)
{
size_t x = sizeof p; /* gives size of pointer, in bytes, probably 4 */
}

void bar(int *q, size_t nobj)
{
while(nobj--)
{
*q++ = 42;
}
}

int main(void)
{
int arr[20] = {0};
size_t y = sizeof arr; /* gives size of array, in bytes, probably 80 */
foo(arr); /* not good enough */
bar(arr, sizeof arr / sizeof arr[0]); /* good enough */
return 0;
}
Agreed, fully.
 
M

Martin Ambuhl

Frodo said:
Hi
I need to know the size of the memory block pointed to by a char* in a
function receiving this pointer. Typically, this pointer points to a
string. strlen() will not do the job since sometimes the string is not
null terminated.

A string is alway '\0' terminated by definition. You mean 'char array'.
That is:


int foo(void)
{
/* ...... */
char buf[20];
a(buf);
/* ....... */
return 0;
}
void a(char* ptr)
{
/* Here, I need the length of the mem block pointed at by ptr */
pass the value to a() [which needs a prior declaration anyway,
the implicit declaration will cause a redefinition error in C89
and is not sufficient in C99 even for functions returning int].
A suitable signature for a() might be
void a(size_t n, char *p);
 
C

CBFalconer

matevzb said:
No, it will not. Arrays decay into pointers when passed to a
function, so once inside a function, it's too late to get the size
information (see http://c-faq.com/aryptr/aryptrparam.html for more
detail). As Chris suggested, pass the size as a parameter to the
called function.

sizeof is an operator, not a function. Look up its definition (in
the standard). From N869:

6.3.2.1 Lvalues and function designators

.... snip ...

[#2] Except when it is the operand of the sizeof operator,
the unary & operator, the ++ operator, the -- operator, or
the left operand of the . operator or an assignment
operator, an lvalue that does not have array type is
converted to the value stored in the designated object (and
is no longer an lvalue). If the lvalue has qualified type,
the value has the unqualified version of the type of the
lvalue; otherwise, the value has the type of the lvalue. If
the lvalue has an incomplete type and does not have array
type, the behavior is undefined.
 
R

Richard Heathfield

CBFalconer said:
sizeof is an operator, not a function.

matevzb didn't claim that sizeof is a function. His mention of "a function"
was related to the OP's question, not to dbtid's sizeof(a).
 
D

dbtid

Richard said:
matevzb said:


Yes, it will. But the OP can't use sizeof because he's not actually getting
an array, merely a pointer.


And the function thus does not receive an array parameter (not least because
there's no such thing), but a pointer parameter, and so sizeof will yield
not the size of the array in bytes but the size of the pointer in bytes.


Right again.

Yeah, that's the part I didn't mention: he should pass sizeof (a) (the
array) to the function as a parameter.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top