470,849 Members | 1,098 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,849 developers. It's quick & easy.

memfrob and strfry ? OT

My string.h headers declares two functions I have been using called
memfrob and strfry. They are encryption types functions. My man pages say
they are standard to linux c and gnu c. They sure aren't in my C books.
Interesting functions by they're OT here but this raises to me a question.
If a function returns a pointer to a void and and as it's first parameter a
pointer to a void. Then should that function's first parameter accept a
string or pointer to char or any other data type since the parameter is
declared a void * ?

Bill
Jun 27 '08 #1
35 5319
In article <Kl2Zj.25383$sX5.23589@trnddc02>,
Bill Cunningham <no****@nspam.comwrote:
My string.h headers declares two functions I have been using called
memfrob and strfry.
Laugh? I almost did.

-- Richard
--
:wq
Jun 27 '08 #2

"Richard Tobin" <ri*****@cogsci.ed.ac.ukwrote in message
news:g1***********@pc-news.cogsci.ed.ac.uk...
Laugh? I almost did.

-- Richard
<gigglewell it is kinda funny. Strfry looks like stirfry and memfrob
like some kind of frog. But no kidding they exist.

Bill
Jun 27 '08 #3
"Bill Cunningham" <no****@nspam.comwrites:
My string.h headers declares two functions I have been using called
memfrob and strfry. They are encryption types functions. My man pages say
they are standard to linux c and gnu c. They sure aren't in my C books.
Interesting functions by they're OT here but this raises to me a question.
If a function returns a pointer to a void and and as it's first parameter a
pointer to a void. Then should that function's first parameter accept a
string or pointer to char or any other data type since the parameter is
declared a void * ?
Since you're asking about what it accepts as an argument, the type
that it returns is irrelevant. And since strfry() takes an argument
of type char* and returns a char* result, it's also irrelevant. The
only thing you're asking about is the first parameter of memfrob().

For reference, the declaration is:

void *memfrob(void *s, size_t n);

(The function itself is off-topic; the fact that you can declare a
function like that is not. The use of a name starting with "mem"
raises some issues that I'll ignore.)

Any pointer type (other than a pointer-to-function type) can be
implicitly converted to void*. So the first argument in a call to
memfrob() can be an expression of any pointer type other than a
pointer-to-function type. (This includes array expressions, such as
string literals, which are converted to pointer values.) It can also
be a null pointer constant, such as the macro NULL or a literal 0
(though you wouldn't want to pass a null pointer to memfrob()).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #4

"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...

[snip]
Any pointer type (other than a pointer-to-function type) can be
implicitly converted to void*. So the first argument in a call to
memfrob() can be an expression of any pointer type other than a
pointer-to-function type. (This includes array expressions, such as
string literals, which are converted to pointer values.) It can also
be a null pointer constant, such as the macro NULL or a literal 0
(though you wouldn't want to pass a null pointer to memfrob()).
Thank you Keith. So if I wanted a function to return any number of types
as well as a void should a function return a void? That's my question.

Bill
Jun 27 '08 #5
"Bill Cunningham" <no****@nspam.comwrites:
"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...

[snip]
>Any pointer type (other than a pointer-to-function type) can be
implicitly converted to void*. So the first argument in a call to
memfrob() can be an expression of any pointer type other than a
pointer-to-function type. (This includes array expressions, such as
string literals, which are converted to pointer values.) It can also
be a null pointer constant, such as the macro NULL or a literal 0
(though you wouldn't want to pass a null pointer to memfrob()).
Thank you Keith. So if I wanted a function to return any number
of types as well as a void should a function return a void? That's
my question.
No, that's an entirely new question, to which the answer is no.

A function declared to return void doesn't return anything.

A function declared to return void* (a very different thing from void)
returns what you can think of as a generic pointer; it can point to
any object. But to do that, there has to be an object for it to point
to, (which means you have think about allocating and deallocating it),
and you have to know somehow what type it points to if you want to do
anything with it.

What problem are you trying to solve? It's very likely that "a
function to return any number of types" isn't the right solution.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #6

"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...

[snip]
What problem are you trying to solve? It's very likely that "a
function to return any number of types" isn't the right solution.
I've been working with this OT function memfrb. It's a type I've never
encountered. I wouldn't know how in C to take a block of memory I tried 64
bytes the partition table I saved from a mbr. I thought I'd use this to
encypt some bytes. Closest I got was some garbage and a segmention fault.

void *pv;
pv=memfrb("file",64);
printf("%s\n",pv);

Didn't work.

printf("%s\n",(memfrob("b",64));

didn't work. How would you use this type of function? Not so much memfrob
but a function that returned a void* and took a void*s as a first parameter.
I've never worked with voids is the simple statement. I wouldn't know what
to do with this one.

Bill
Jun 27 '08 #7
"Bill Cunningham" <no****@nspam.comwrites:
"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...

[snip]
>What problem are you trying to solve? It's very likely that "a
function to return any number of types" isn't the right solution.
I've been working with this OT function memfrb. It's a type I've never
encountered. I wouldn't know how in C to take a block of memory I tried 64
bytes the partition table I saved from a mbr. I thought I'd use this to
encypt some bytes. Closest I got was some garbage and a segmention fault.

void *pv;
pv=memfrb("file",64);
printf("%s\n",pv);
It's "memfrob", not "memfrb". This typo indicates that you didn't
copy-and-paste your actual code, so I can't reliably infer anything.

Again, for reference, the declaration is:

void *memfrob(void *s, size_t n);

It's a very very poor encryption routine (it merely xors each byte
with the number 42). It can defeat a rudimentary attempt to search
for readable strings, nothing more.
Didn't work.
Well of course it didn't work. Your call

memfrob("file", 64);

attempts to modify the first 64 bytes of the string literal "file".
This immediately invokes undefined behavior by (a) attempting to
modify a string literal, and (b) attempting to modify 64 bytes of a
5-byte object.

If you want to "encrypt" data from a file, you first need to open the
file, and then read the data from the file. Passing the string "file"
to memfrob(), or to any other non-I/O function, will not magically
access a file named "file".
printf("%s\n",(memfrob("b",64));
And what is "b" supposed to be?
didn't work. How would you use this type of function? Not so much memfrob
but a function that returned a void* and took a void*s as a first parameter.
I've never worked with voids is the simple statement. I wouldn't know what
to do with this one.
Ok, you want to learn about void*.

My advice: Forget about memfrob(). It's non-standard, and it doesn't
do anything particularly useful. Take a look at the various standard
mem*() functions: memcpy, memmove, memcmp, memchr, memset. To start
learning about them, read a book.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #8
On 22 May, 00:36, "Bill Cunningham" <nos...@nspam.comwrote:
My string.h headers declares two functions I have been using called
memfrob and strfry. They are encryption types functions. My man pages say
they are standard to linux c and gnu c. They sure aren't in my C books.
Interesting functions by they're OT here but this raises to me a question.
If a function returns a pointer to a void and and as it's first parameter a
pointer to a void. Then should that function's first parameter accept a
string or pointer to char or any other data type since the parameter is
declared a void * ?
What you should pass as a first parameter depends on what the function
does. For example realloc() accepts as a first parameter void * but
you
cannot pass anything you want to it , it has to be either NULL or a
pointer previously returned by malloc() or realloc().

On 22 May, 03:06, "Bill Cunningham" <nos...@nspam.comwrote:
How would you use this type of function? Not so much memfrob
but a function that returned a void* and took a void*s as a first parameter.
I've never worked with voids is the simple statement. I wouldn't know what
to do with this one.
Find some code which uses realloc() and study it.

Jun 27 '08 #9
On 22 May, 01:03, Keith Thompson <ks...@mib.orgwrote:
"Bill Cunningham" <nos...@nspam.comwrites:
My string.h headers declares two functions I have been using called
memfrob and strfry. They are encryption types functions. My man pages say
they are standard to linux c and gnu c. They sure aren't in my C books.
Interesting functions by they're OT here but this raises to me a question.
If a function returns a pointer to a void and and as it's first parameter a
pointer to a void. Then should that function's first parameter accept a
string or pointer to char or any other data type since the parameter is
declared a void * ?

<SNIP>

Any pointer type (other than a pointer-to-function type) can be
implicitly converted to void*.
Of course on Linux a void * can hold even pointers to functions.

Jun 27 '08 #10
Richard Tobin wrote:
In article <Kl2Zj.25383$sX5.23589@trnddc02>,
Bill Cunningham <no****@nspam.comwrote:
My string.h headers declares two functions I have been using
called memfrob and strfry.

Laugh? I almost did.
I had Hunan chicken for lunch. Oh wait, that's stir-fry.

Brian
Jun 27 '08 #11
Default User wrote:
Richard Tobin wrote:
>In article <Kl2Zj.25383$sX5.23589@trnddc02>,
Bill Cunningham <no****@nspam.comwrote:
>> My string.h headers declares two functions I have been using
called memfrob and strfry.
Laugh? I almost did.

I had Hunan chicken for lunch. Oh wait, that's stir-fry.
Illegal. Can't use the hyphen here. Maybe stir_fry. :-)

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Jun 27 '08 #12
On 22 May 2008 at 3:35, Spiros Bousbouras wrote:
Of course on Linux a void * can hold even pointers to functions.
And more generally on POSIX. Actually, like so many things, this is
really Not A Problem in real life, but the clc regulars try to make it
into a problem so that they've got something to beef about.

Jun 27 '08 #13

"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
Ok, you want to learn about void*.

My advice: Forget about memfrob(). It's non-standard, and it doesn't
do anything particularly useful. Take a look at the various standard
mem*() functions: memcpy, memmove, memcmp, memchr, memset. To start
learning about them, read a book.
Here's what I have learned. Sec 5.4 pg 103. "...except for void *, to
assign a pointer of one type to a pointerr of another type withou a
cast." --k and r 2

Bill
Jun 27 '08 #14

"Spiros Bousbouras" <sp****@gmail.comwrote in message
news:1467c554-96c0-48d3-8ee8-
Find some code which uses realloc() and study it.
That's the thing. I can't find any. I have about 64 bytes worth of
partition table data I can play with. According to what I've read this
function changes the size somehow.

Bill
Jun 27 '08 #15
Bill Cunningham wrote:
"Spiros Bousbouras" <sp****@gmail.comwrote:
>Find some code which uses realloc() and study it.

That's the thing. I can't find any. I have about 64 bytes worth
of partition table data I can play with. According to what I've
read this function changes the size somehow.
#include <stdio.h>
#include <stdlib.h>

int main(void) {
void *t, *p, *pp;
size_t sz;

p = malloc(1);
for (sz = 2; sz < 100; sz++) {
pp = p;
if (t = realloc(p, sz)) p = t;
else {
printf("realloc failed at sz = %lu\n", (unsigned long)sz);
break;
}
printf("p was %p, is %p at sz = %lu\n",
pp, p, (unsigned long)sz);
}
return 0;
}

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
** Posted from http://www.teranews.com **
Jun 27 '08 #16
On Thu, 22 May 2008 21:51:35 +0000, Antoninus Twink wrote:
On 22 May 2008 at 3:35, Spiros Bousbouras wrote:
>Of course on Linux a void * can hold even pointers to functions.

And more generally on POSIX.
Wrong.
Jun 27 '08 #17
On 23 May 2008 at 16:47, Harald van Dijk wrote:
On Thu, 22 May 2008 21:51:35 +0000, Antoninus Twink wrote:
>On 22 May 2008 at 3:35, Spiros Bousbouras wrote:
>>Of course on Linux a void * can hold even pointers to functions.

And more generally on POSIX.

Wrong.
In that case, what do you do with the void * returned by dlsym()? Put it
on a shelf and admire its object-pointer-ness?

Jun 27 '08 #18
Harald van Dijk <tr*****@gmail.comwrites:
On Thu, 22 May 2008 21:51:35 +0000, Antoninus Twink wrote:
>On 22 May 2008 at 3:35, Spiros Bousbouras wrote:
>>Of course on Linux a void * can hold even pointers to functions.

And more generally on POSIX.

Wrong.
<OT>
See <http://www.opengroup.org/onlinepubs/009695399/functions/dlsym.html>,
particularly the rationale section.
</OT>

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #19
In article <sl*******************@nospam.invalid>,
Antoninus Twink <no****@nospam.invalidwrote:
>On 23 May 2008 at 16:47, Harald van Dijk wrote:
>On Thu, 22 May 2008 21:51:35 +0000, Antoninus Twink wrote:
>>On 22 May 2008 at 3:35, Spiros Bousbouras wrote:
Of course on Linux a void * can hold even pointers to functions.

And more generally on POSIX.

Wrong.

In that case, what do you do with the void * returned by dlsym()? Put it
on a shelf and admire its object-pointer-ness?
Is dlsym() POSIX?

I would assume that that is the picky point being made. And I would
assume that the answer is "no", FSVO "POSIX".

Probably some early draft release...

Jun 27 '08 #20
On Fri, 23 May 2008 10:31:23 -0700, Keith Thompson wrote:
Harald van Dijk <tr*****@gmail.comwrites:
>On Thu, 22 May 2008 21:51:35 +0000, Antoninus Twink wrote:
>>On 22 May 2008 at 3:35, Spiros Bousbouras wrote:
Of course on Linux a void * can hold even pointers to functions.

And more generally on POSIX.

Wrong.

<OT>
See
<http://www.opengroup.org/onlinepubs/009695399/functions/dlsym.html>,
particularly the rationale section.
POSIX does not require implementations to support dlsym; see the synopsis.
</OT>
Getting back on topic, the rationale is wrong about the C standard. It
states:

"Note that compilers conforming to the ISO C standard are required to
generate a warning if a conversion from a void * pointer to a function
pointer is attempted as in:
fptr = (int (*)(int))dlsym(handle, "my_function");"

This is not a syntax error and violates no constraints. While the C
standard does not define the behaviour of a conversion from void * to a
function pointer type, it allows implementations to accept them without
any diagnostic. The only constraint on casts is that both types involved
are scalar. void * is, and so is int(*)(int). In fact, I'm not even sure
if implementations are allowed to reject the cast (even though some do)
unless they can prove the code will always be reached.
Jun 27 '08 #21
In article <44***************************@cache6.tilbu1.nb.ho me.nl>,
Harald van =?UTF-8?b?RMSzaw==?= <tr*****@gmail.comwrote:
>Getting back on topic, the rationale is wrong about the C standard. It
states:
>"Note that compilers conforming to the ISO C standard are required to
generate a warning if a conversion from a void * pointer to a function
pointer is attempted as in:
fptr = (int (*)(int))dlsym(handle, "my_function");"
>This is not a syntax error and violates no constraints.
It is not one of the allowed casts in C89 3.3.4 Cast Operators.
C89 3.3.4 allows pointers to function types to be converted
to pointers to other function types, but there is no provision
there for conversion between function type and void*.

The conversions for void* are described in C89 3.2.2.3 Pointers,
which only describes the conversions between void* and pointers
to objects or pointer to incomplete types.

If your point is that there isn't any paragraph that specifically
says that it is not permissible to convert between void* and function
pointers, then that would be correct, but neither does the C89
standard specifically make the result implementation defined. I take
it then, that you are going for a "That which is not forbidden is
permissible" interpretation ?
--
"A scientist who cannot prove what he has accomplished,
has accomplished nothing." -- Walter Reisch
Jun 27 '08 #22

"CBFalconer" <cb********@yahoo.comwrote in message
news:48***************@yahoo.com...
#include <stdio.h>
#include <stdlib.h>

int main(void) {
void *t, *p, *pp;
size_t sz;

p = malloc(1);
for (sz = 2; sz < 100; sz++) {
pp = p;
if (t = realloc(p, sz)) p = t;
else {
printf("realloc failed at sz = %lu\n", (unsigned long)sz);
break;
}
printf("p was %p, is %p at sz = %lu\n",
pp, p, (unsigned long)sz);
}
return 0;
}
Whew. Lets see if I can break this down and digest it. It looks like
malloc and realloc go together.

p = malloc(1);
for (sz = 2; sz < 100; sz++) {
pp = p;
if (t = realloc(p, sz)) p = t;
p=t is outside of the parenthesis. It looks like some shorthand I am not
good enough to decipher. I will compile this and see what happens.

Code by CB Falconer.

Bill

Jun 27 '08 #23
On Fri, 23 May 2008 19:00:14 +0000, Walter Roberson wrote:
In article <44***************************@cache6.tilbu1.nb.ho me.nl>,
Harald van =?UTF-8?b?RMSzaw==?= <tr*****@gmail.comwrote:
>>Getting back on topic, the rationale is wrong about the C standard. It
states:
>>"Note that compilers conforming to the ISO C standard are required to
generate a warning if a conversion from a void * pointer to a function
pointer is attempted as in:
fptr = (int (*)(int))dlsym(handle, "my_function");"
>>This is not a syntax error and violates no constraints.
[...]
If your point is that there isn't any paragraph that specifically says
that it is not permissible to convert between void* and function
pointers, then that would be correct,
Yes, that is my point.
but neither does the C89 standard
specifically make the result implementation defined. I take it then,
that you are going for a "That which is not forbidden is permissible"
interpretation ?
When the behaviour is undefined (explicitly or by omission), there is no
requirement for a diagnostic. The standard is quite explicit about this in
a note:

3.4.3p2:
"NOTE Possible undefined behavior ranges from ignoring the situation
completely with unpredictable results, to [...]"

Additionally, when the behaviour would be undefined, except the code is
never executed, then the standard isn't entirely clear whether
implementations are allowed to reject it, but a DR cleared that up:
they're not. It's DR #109, if you would like to look it up yourself as
well.

int f(void) { return 1/0; }
int main(void) {}

This is a strictly conforming program. Any implementation that rejects it,
however useful it may be, fails to conform to the C standard. I believe
the same applies to casts between object and function pointer types, as
the behaviour is simply not defined by the standard, and there is supposed
to be no difference between behaviour undefined by omission, and behaviour
that's explicitly undefined.
Jun 27 '08 #24
Bill Cunningham wrote:
>
"CBFalconer" <cb********@yahoo.comwrote in message
news:48***************@yahoo.com...
>#include <stdio.h>
#include <stdlib.h>

int main(void) {
void *t, *p, *pp;
size_t sz;

p = malloc(1);
for (sz = 2; sz < 100; sz++) {
pp = p;
if (t = realloc(p, sz)) p = t;
else {
printf("realloc failed at sz = %lu\n", (unsigned long)sz);
break;
}
printf("p was %p, is %p at sz = %lu\n",
pp, p, (unsigned long)sz);
}
return 0;
}
Whew. Lets see if I can break this down and digest it. It looks
like
malloc and realloc go together.

p = malloc(1);
> for (sz = 2; sz < 100; sz++) {
pp = p;
if (t = realloc(p, sz)) p = t;

p=t is outside of the parenthesis. It looks like some shorthand I
am not
good enough to decipher. I will compile this and see what happens.
The realloc function is called to resize memory pointed to by 'p' to the
new size specified by 'sz'. The return value of realloc is assigned
to 't' and the resultant value of the expression is evaluated to see
whether it is "true" (non-zero value) or "false" (zero). So if realloc
succeeds the expression within the parenthesis would evaluate to true
and if realloc fails it would evaluate to false. If it evaluates as
true then the statement controlled by the if is executed, which in this
case just assigns the value in 't' to 'p', i.e., copies the new pointer
value realloc has returned into 'p'. It has to be done this way because
realloc can fail in which case the original memory is left untouched.
If the return from realloc were to be assigned to 'p' before checking
for failure then we would lose access to the original memory in the
event of realloc failure (unless the value previously in 'p' has been
cached elsewhere).

Jun 27 '08 #25

"santosh" <sa*********@gmail.comwrote in message
news:g1**********@registered.motzarella.org...
The realloc function is called to resize memory pointed to by 'p' to the
new size specified by 'sz'. The return value of realloc is assigned
to 't' and the resultant value of the expression is evaluated to see
whether it is "true" (non-zero value) or "false" (zero). So if realloc
succeeds the expression within the parenthesis would evaluate to true
and if realloc fails it would evaluate to false. If it evaluates as
true then the statement controlled by the if is executed, which in this
case just assigns the value in 't' to 'p', i.e., copies the new pointer
value realloc has returned into 'p'. It has to be done this way because
realloc can fail in which case the original memory is left untouched.
If the return from realloc were to be assigned to 'p' before checking
for failure then we would lose access to the original memory in the
event of realloc failure (unless the value previously in 'p' has been
cached elsewhere).
Can I see this code without any type of error checking? Just plain old
calls? I seem to learn the concepts better with plain old code to serve a
purpose before error checking is added.

Bill
Jun 27 '08 #26
Antoninus Twink <no****@nospam.invalidwrote:
On 22 May 2008 at 3:35, Spiros Bousbouras wrote:
Of course on Linux a void * can hold even pointers to functions.

And more generally on POSIX. Actually, like so many things, this is
really Not A Problem in real life, but the clc regulars try to make it
into a problem so that they've got something to beef about.
There are real machines that are really in use in the real world that
have function pointers that are larger than data pointers and don't fit
in a void *. There may not be very many of them, but they're not
imaginary.

-- Larry Jones

That's the problem with nature. Something's always stinging you
or oozing mucus on you. -- Calvin
Jun 27 '08 #27
Bill Cunningham wrote:
>
"santosh" <sa*********@gmail.comwrote in message
news:g1**********@registered.motzarella.org...
>The realloc function is called to resize memory pointed to by 'p' to
the new size specified by 'sz'. The return value of realloc is
assigned to 't' and the resultant value of the expression is
evaluated to see whether it is "true" (non-zero value) or "false"
(zero). So if realloc succeeds the expression within the parenthesis
would evaluate to true and if realloc fails it would evaluate to
false. If it evaluates as true then the statement controlled by the
if is executed, which in this case just assigns the value in 't' to
'p', i.e., copies the new pointer value realloc has returned into
'p'. It has to be done this way because realloc can fail in which
case the original memory is left untouched. If the return from
realloc were to be assigned to 'p' before checking for failure then
we would lose access to the original memory in the event of realloc
failure (unless the value previously in 'p' has been cached
elsewhere).

Can I see this code without any type of error checking? Just plain
old
calls? I seem to learn the concepts better with plain old code to
serve a purpose before error checking is added.
#include <stdio.h>
#include <stdlib.h>

int main(void) {
void *t, *p, **pp;
size_t sz;

p = malloc(1);
for (sz = 2; sz < 100; sz++) {
pp = p;
p = realloc(p, sz);
printf("p was %p, is %p at sz = %lu\n",
pp, p, (unsigned long)sz);
}
return 0;
}

Jun 27 '08 #28
"CBFalconer" <cb********@yahoo.comwrote in message
news:48***************@yahoo.com...
Bill Cunningham wrote:
>"Spiros Bousbouras" <sp****@gmail.comwrote:
>>Find some code which uses realloc() and study it.

That's the thing. I can't find any. I have about 64 bytes worth
of partition table data I can play with. According to what I've
read this function changes the size somehow.

#include <stdio.h>
#include <stdlib.h>

int main(void) {
void *t, *p, *pp;
size_t sz;

p = malloc(1);
for (sz = 2; sz < 100; sz++) {
pp = p;
if (t = realloc(p, sz)) p = t;
else {
printf("realloc failed at sz = %lu\n", (unsigned long)sz);
break;
}
printf("p was %p, is %p at sz = %lu\n",
pp, p, (unsigned long)sz);
}
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

free(p);
return 0;
}
[...]
;^)

Jun 27 '08 #29
"Bill Cunningham" <no****@nspam.comwrites:
"CBFalconer" <cb********@yahoo.comwrote in message
news:48***************@yahoo.com...
[...]
> if (t = realloc(p, sz)) p = t;

p=t is outside of the parenthesis. It looks like some shorthand I am not
good enough to decipher. I will compile this and see what happens.
It's just an if statement; the fact that the controlled statement is
on the same line as the if makes no difference to the compiler. It's
no uncommon to write a compound statement on one line if it's short
enough (though some would argue that it's poor style).

The following are all equivalent:

if (condition) statement;

if (condition)
statement;

if (condition)
{
statement;
}

Actually the latter can be different depending on what follows it, but
in isolation they all mean the same thing.

In most contexts, whitespace and line endings do not affect the
meaning of a piece of C code *as far as the compiler is concerned*
(though they can be vitally important to human readers trying to
understand it).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #30

"santosh" <sa*********@gmail.comwrote in message
news:g1**********@registered.motzarella.org...
#include <stdio.h>
#include <stdlib.h>

int main(void) {
void *t, *p, **pp;
size_t sz;

p = malloc(1);
for (sz = 2; sz < 100; sz++) {
pp = p;
p = realloc(p, sz);
printf("p was %p, is %p at sz = %lu\n",
pp, p, (unsigned long)sz);
}
return 0;
}
That is much better. I guess the only thing I don't see is the pupose
for the pp=p; statement.

Bill
Jun 27 '08 #31
On May 23, 2:15*pm, santosh <santosh....@gmail.comwrote:
>
#include <stdio.h>
#include <stdlib.h>

int main(void) {
* void *t, *p, **pp;
* size_t sz;

* p = malloc(1);
* for (sz = 2; sz < 100; sz++) {
* * pp = p;
* * p = realloc(p, sz);
* * printf("p was %p, is %p at sz = %lu\n",
* * * * * * * *pp, * * * *p, * (unsigned long)sz);
While I understand the intent here in replying to Bill C., it should
be noted that if realloc causes the allocated area to move (p != pp),
then this code invokes undefined behavior. The standard states that
the value of a pointer (pp in this case) becomes indeterminate when
the object it points to (in this case the allocated memory) ceases to
exist. Any attempt to evaluate an indeterminate value is prohibited.
* }
* return 0;
Jun 27 '08 #32

"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
malloc() allocates a chunk of memory. realloc() resizes a chunk of
memory that's already been allocated, possibly copying it to a new
location. free() deallocations a chunk of memory that was allocated
by malloc() and/or realloc().
So that's what they do ok.
What exactly are you trying to accomplish?
Insead of reading from ram read into ram a file of data.

Bill

Jun 27 '08 #33
On May 24, 11:16*am, "Bill Cunningham" <nos...@nspam.comwrote:
>
What exactly are you trying to accomplish?

* * Insead of reading from ram read into ram a file of data.
To read from a file into memory, you first must define or allocate a
buffer. It can be as small as a single char or as large as your
system will allow. A typical example would be an array of char.

Before you can read, you must open the file usign fopen. After
checking that fopen succeeded, you have several otions to actually
transfer the data. fgetc will transfer a single character. fgets
will real a line if the fileis text. fread will read a block of
data. There are others. You chose the one that suits your needs.
When you are done processing the file, you close it with fclose.
Jun 27 '08 #34

"santosh" <sa*********@gmail.comwrote in message
news:g1**********@registered.motzarella.org...
#include <stdio.h>
#include <stdlib.h>

int main(void) {
void *t, *p, **pp;
size_t sz;

p = malloc(1);
for (sz = 2; sz < 100; sz++) {
pp = p;
p = realloc(p, sz);
printf("p was %p, is %p at sz = %lu\n",
pp, p, (unsigned long)sz);
}
return 0;
}
I'm beginning to see what pointers are for and it's new to me at this
stage. Pointers in the past to me have just been another way to use arrays.
Can I have an example of malloc by itself? Or is it not used by itself? For
what reasons would you use malloc?

Bill
Jun 27 '08 #35
Bill Cunningham wrote:
>
"santosh" <sa*********@gmail.comwrote in message
news:g1**********@registered.motzarella.org...
>#include <stdio.h>
#include <stdlib.h>

int main(void) {
void *t, *p, **pp;
size_t sz;

p = malloc(1);
for (sz = 2; sz < 100; sz++) {
pp = p;
p = realloc(p, sz);
printf("p was %p, is %p at sz = %lu\n",
pp, p, (unsigned long)sz);
}
return 0;
}

I'm beginning to see what pointers are for and it's new to me at
this
stage. Pointers in the past to me have just been another way to use
arrays. Can I have an example of malloc by itself?
Sure:

int *blk;

blk = malloc(ELEMENTS * sizeof *blk);
/* In serious program you must check the return value
of malloc before proceeding. I omitted it here because
you have previously expressed difficulty understanding code
with error checking included.
*/

Here we have called malloc to attempt an allocation of ELEMENTS*sizeof
*blk bytes of memory. ELEMENTS must be defined and set to an
appropriate value previously. After the function has succeeded you
have 'blk' pointing to a contiguous sequence of the amount of bytes of
memory you passed to malloc. By accessing them through 'blk' they are
treated as an array of ELEMENTS ints. You could've also assigned the
return value to another type of pointer (say double or unsigned char)
in which case the memory is treated as a sequence of objects of the
appropriate type. This is done automatically by your compiler.
Or is it not used
by itself?
It's often used by itself.
For what reasons would you use malloc?
Malloc is used when you need to allocate storage during runtime, i.e.,
you do not know how much memory you will need until after the program
is running (for example it might depend on user or other device input).
Statically allocated memory is out-of-question while VLA have other
drawbacks (they have a smaller scope and lifetime and they is no
portable way to detect or recover from a VLA allocation failure).

Also dynamically allocated memory persists for exactly as long as you
want, no more no less. Global objects persist throughout the program's
lifetime whether or not you want that while local objects are destroyed
when their scope is exited, and again there is nothing you can do about
that. Memory derived through malloc (or realloc or calloc) is available
until you deallocate it with free or until the program terminates.

Jun 27 '08 #36

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.