keyongtech


  keyongtech > c > 10/2008

 #106  
09-17-08, 08:17 AM
Richard Heathfield
arnuld said:

>> On Wed, 17 Sep 2008 06:29:37 +0000, Richard Heathfield wrote:

>
>> Yes, you could do that, except that (a) it might not be the user's
>> stupid fault (it may simply be that your machine is low on memory), and
>> (b) there may be a way to recover. If this is a mere learning exercise
>> and the learning task is not error recovery, then yes, by all means bomb
>> out. That's the "student solution" and, like cryptosporidium, is very
>> common.

>
> [..]
>
> ..aye.... , so lets learn the practical aspects like error-recovery too.
> I don't like academic solutions BTW


I have discussed recovering from an allocation failure several times in
this group. In message <3D6BE31E.ACBADD1E>, for
example, I listed five alternatives to giving up and dying.
 #107  
09-17-08, 08:28 AM
Nick Keighley
On 17 Sep, 07:17, Ron Ford <r...@example.invalid> wrote:
> On Tue, 16 Sep 2008 06:28:30 +0000, Richard Heathfield posted:


<snip>

>> I think it's about here that I like to pretend I'm from Missouri.
>> Show me.

>
> As it polls redder with the Palin nomination, Huck sighed, 'Ashcroft
> sucks."


if you have a political point to make then do it in english.
Or, better, don't make the point on a technical news group.
 #108  
09-17-08, 08:34 AM
Nick Keighley
On 17 Sep, 07:59, arnuld <sunr...@invalid.address> wrote:
> > On Wed, 17 Sep 2008 06:29:37 +0000, Richard Heathfield wrote:


> > Yes, you could do that, except that (a) it might not be the user's stupid
> > fault (it may simply be that your machine is low on memory), and (b) there
> > may be a way to recover. If this is a mere learning exercise and the
> > learning task is not error recovery, then yes, by all means bomb out.
> > That's the "student solution" and, like cryptosporidium, is very common.

>
> [..]
>
> ..aye.... , so lets learn the practical aspects like error-recovery too. I
> don't like academic solutions BTW


when, exactly, did "academic" become a pejorative term?


"Yes it works in practice - but does it work in theory?"

"There is nothing as practical as a good theory."
 #109  
09-17-08, 08:38 AM
Richard Heathfield
Ron Ford said:

<snip>

> As it polls redder with the Palin nomination, Huck sighed, 'Ashcroft
> sucks."


I don't understand what this has to do with the subject of discussion. In
fact, you frequently baffle me with incomprehensible replies that seem to
bear no relation to what is being discussed or indeed to anything
whatsoever. Is this deliberate? If so, please stop. Think about it - the
more you jar people off, the less help you'll get with your C questions.
 #110  
09-17-08, 08:45 AM
Richard Heathfield
Nick Keighley said:

> On 17 Sep, 07:59, arnuld <sunr...@invalid.address> wrote:


<snip>

>> ..aye.... , so lets learn the practical aspects like error-recovery too.
>> I don't like academic solutions BTW

>
> when, exactly, did "academic" become a pejorative term?


What makes you think he's using it pejoratively? He's just saying he
doesn't like academic solutions. I don't like salmon, but that doesn't
mean I consider "salmon" to be a pejorative term.

> "Yes it works in practice - but does it work in theory?"
>
> "There is nothing as practical as a good theory."


This isn't about theory vs practice, but about good practice vs indifferent
practice.
 #111  
09-17-08, 09:13 AM
arnuld
> On Wed, 17 Sep 2008 06:57:38 +0000, Richard Heathfield wrote:

>> arnuld said:



> *pc = calloc(AVERAGE_SIZE - 1, sizeof **pc);


why sizeof **pc and not sizeof *pc ?



>> pc_begin = *pc;
>>
>> if( (! *pc) )
>> {
>> perror("can not allocate memory, sorry babe!");
>> return 1;
>> }


> Okay - although it's better not to embed messages like this in library
> functions if you can avoid it.



its *not* a library function. its my function. and which message you are
talking about, perror or return call ?



> Don't forget to check that return value in the caller.


yes, will do that when get_words will be ready.



> I thought you wanted to stop at whitespace?
>
> Also, it's better to move pc_begin than *pc, if you must move either of
> them. Given that you have idx keeping track of things, I see no reason to
> modify *pc (and plenty of reasons not to), and no reason for pc_begin to
> exist at all. You can simply do (*pc)[idx] = ch;


Because [] make it look like an array when you can never pass an array in
C, you always pass a pointer and that *pc++ reminds of that i am working
in a region of memory starting at *pc and ending at *pc == '\0'. 3rd, when
I start using [] i start forgetting how to use pointers.

pc_begin is there because i have rad enough that any callto malloc/calloc
*must* be accompanied by call to free(), other wise we will have a memory
leak. Since I am moving the original pointer (pc), I use pc_begin to save
the beginning position of original pointer, so that I can pass that to
free().


>> *++pc = '\0';


> pc is char **, so ++pc is char ** (and utterly invalid),


invalid ? I am moving the pointer to next value, so that I can assign to
the **pc .


> and *++pc is char*, so you're setting a wild pointer to 0. Not good. Could
> be worse, but not good.


That should be **++pc , my typo in the original code.




> *pc = calloc(cursize, sizeof **pc);


why sizeof **pc, why not sizeof(char*) ?



> new = realloc(*pc, 2 * cursize * sizeof *new);


Same question. Why sizeof *new rather than sizeof char* ?



> if(GSW_OK == rc)
> {
> pc_begin[idx++] = ch;
> }


is it the same as **pc++ = ch; ? I think it is. Last, you did not free
the memory. Here is my code without realloc. First I will make calloc work
then I think about realloc. It Segfaults BTW :




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


enum { AVERAGE_SIZE = 28 };

enum { GSW_OK, GSW_ENOMEM, GSW_ENORESIZE } ;


int get_single_word( char** );


int main( void )
{
char* pw; /* pw means pointer to word */

get_single_word( &pw );

printf("word you entered is: %s\n", pw);

return 0;
}



int get_single_word( char** pc )
{
int ret_value;
unsigned idx;
int ch;

size_t curr_size;
char* pc_begin;


*pc = calloc(curr_size, sizeof (char*));

if( *pc )
{
ret_value = GSW_OK;
pc_begin = *pc;
}
else
{
ret_value = GSW_ENOMEM;
return ret_value;
}

while( ( (ch = getchar()) != EOF) && isspace( (unsigned char)ch ))
{
continue; /* Leading whitespace, protection from some stupid user */
}

for( idx = 0; (ch = getchar()) && (! isspace((unsigned char) ch)); ++idx )
{
if( curr_size == idx )
{
/* realloc, we will think about it later.
use input of size less than ARRSIZE characters for now */
}

if( GSW_OK == ret_value )
{
**pc++ = ch;
}
}


**++pc = '\0';

return ret_value;
}
 #112  
09-17-08, 10:37 AM
Richard Heathfield
arnuld said:

>> On Wed, 17 Sep 2008 06:57:38 +0000, Richard Heathfield wrote:

>
>>> arnuld said:
>>> *pc = calloc(AVERAGE_SIZE - 1, sizeof **pc);

>
> why sizeof **pc and not sizeof *pc ?


Think about it. First satisfy yourself that this is correct:

V = calloc(n, sizeof *V);

You need space sufficient to store the object for which the space is being
allocated, right? So sizeof V, which would only give you the size of the
pointer, would be wrong, yes?

*W = calloc(n, sizeof **W);

Here, we are taking the pointer value returned by calloc and storing it in
an object to which W points. That object, i.e. *W, must itself be a
pointer, and the kind of pointer it must be is the kind of pointer that
points to the kind of thing for which we're allocating space, so sizeof
**W will give us the right size.

Similarly:

**X = calloc(n, sizeof ***X);
***Y = calloc(n, sizeof ****Y);
****Z = calloc(n, sizeof *****Z);


>>> pc_begin = *pc;
>>>
>>> if( (! *pc) )
>>> {
>>> perror("can not allocate memory, sorry babe!");
>>> return 1;
>>> }

>
>> Okay - although it's better not to embed messages like this in library
>> functions if you can avoid it.
>> its *not* a library function. its my function.


You mean you're going to use it once and throw it away? What will you do
the next time you want a function to read a word? Write it from scratch?

> and which message you are
> talking about, perror or return call ?


The perror call. The place to display this kind of error message is in the
application code, which in your case is basically main().

<snip>

> pc_begin is there because i have rad enough that any callto malloc/calloc
> *must* be accompanied by call to free(), other wise we will have a
> memory leak.


You might want to try using the memory before you free it. After you've
freed it, it's too late.

> Since I am moving the original pointer (pc), I use pc_begin
> to save the beginning position of original pointer, so that I can pass
> that to free().


That's rather pointless. If you're not going to use it, don't allocate it.

>> *pc = calloc(cursize, sizeof **pc);

>
> why sizeof **pc, why not sizeof(char*) ?


Why nail a type name into the call? If the type changes, you're stuck with
a maintenance task that my version renders unnecessary.

>> new = realloc(*pc, 2 * cursize * sizeof *new);

>
> Same question. Why sizeof *new rather than sizeof char* ?


Same answer.

>>
>> if(GSW_OK == rc)
>> {
>> pc_begin[idx++] = ch;
>> }

>
> is it the same as **pc++ = ch; ? I think it is. Last, you did not free
> the memory.


Of course I didn't free the memory. Yes, you're right that freeing the
memory is important. It's important to return books to the library too,
but if you're not going to read the book first, why take it out in the
first place?

Anyway, I finally got around to testing my code, and noticed some bugs.
Fixing those gives working code:

(Headers and #defines as before)

int get_single_word( char** pc )
{
int rc = GSW_ENOMEM; /* if we succeed, we'll update the status */
size_t idx = 0;
int ch;
char *pc_begin = NULL;
size_t cursize = AVERAGE_SIZE;
char *new = NULL;

*pc = calloc(cursize, sizeof **pc);
if(*pc != NULL)
{
rc = GSW_OK; /* so far so good */
pc_begin = *pc;

while((ch = getchar()) != EOF && isspace((unsigned char)ch))
{
continue; /* skipping leading whitespace */
}
if(ch != EOF)
{
pc_begin[idx++] = ch;

while(GSW_OK == rc &&
(ch = getchar()) != EOF &&
!isspace((unsigned char)ch))
{
if(cursize == idx + 1)
{
new = realloc(*pc, 2 * cursize * sizeof *new);
if(new == NULL)
{
rc = GSW_ENORESIZE; /* error - couldn't enlarge */
pc_begin[idx] = '\0';
}
else
{
*pc = new;
cursize *= 2;
}
}
if(GSW_OK == rc)
{
pc_begin[idx++] = ch;
}
}
}
}

if(*pc != NULL)
{
pc_begin[idx] = '\0';
}

return rc;
}


I used this main to drive the code:

int main(void)
{
char *word = NULL;
while(get_single_word(&word) == 0 && word[0] != '\0')
{
printf("[%s]\n", word);
free(word);
}
return 0;
}

and for this input:

Now is the time to come to
the aid of the party.

I got this output:

[Now]
[is]
[the]
[time]
[to]
[come]
[to]
[the]
[aid]
[of]
[the]
[party.]
 #113  
09-17-08, 11:18 AM
Ron Ford
On Wed, 17 Sep 2008 07:38:29 +0000, Richard Heathfield posted:

> Ron Ford said:
>
> <snip>
>
>> As it polls redder with the Palin nomination, Huck sighed, 'Ashcroft
>> sucks."

>
> I don't understand what this has to do with the subject of discussion. In
> fact, you frequently baffle me with incomprehensible replies that seem to
> bear no relation to what is being discussed or indeed to anything
> whatsoever. Is this deliberate? If so, please stop. Think about it - the
> more you jar people off, the less help you'll get with your C questions.


Ashcroft must have meant less to you than the Americans he had to shut down
to prepare the way for extraconstitutionality. Among the first deviations
to established law were with DARPA, data mining, and spying on domestic
terrorists, aka democrats.

You can say it has nothing to do with C, the house language of the CIA, but
I'll beg to differ. Their methodology is as flawed as mismatched quotes.

You undercounted by one hundred percent on UB with return (*(int
*)p2)-(*(int *)p1); ask Huck. This is a newsgroup. The fundie
interpretation of the topic--there is no C but C--denies the funner part of
the medium, to say nothing of things that can't be said elsewhere, because
Mitt Romney types own every other medium.

Don't worry, I'll move along. I think 7-5 needs 2 solns, one that just
changes getop, and the better one that Ben could complete. Ciao,
C_Dreamer.

Here's 'show me" in two different languages, one that admits of whitespace,
and the other not, the context for which, of course, you snipped:

'Pokozhautye!'
"Zeig mal!"
 #114  
09-17-08, 12:51 PM
arnuld
> On Wed, 17 Sep 2008 09:37:47 +0000, Richard Heathfield wrote:

> Think about it. First satisfy yourself that this is correct:
>
> V = calloc(n, sizeof *V);


This is from MAN page itself:

The calloc() function shall allocate unused space for an array
of nelem elements each of whose size in bytes is elsize. The space
shall be initialized to all bits 0.

Array elements in your example are of type V, not *V. This is what
confusing me.





> The perror call. The place to display this kind of error message is in
> the application code, which in your case is basically main().


so we *always* use perror() in main() ?




> Anyway, I finally got around to testing my code, and noticed some bugs.
> Fixing those gives working code:



cool :)



> .... SNIP.....


> int main(void)
> {
> char *word = NULL;
> while(get_single_word(&word) == 0 && word[0] != '\0') {
> printf("[%s]\n", word);
> free(word);
> }


we calloc the memory in some other function while freeing it in some
other. Thats really strange. I am not saying its wrong. I am saying its
feels strange for the programmers who has used languages like Lisp,
Python, Ruby and C++ (only using Std. Lib. like string and vector)


I will code the program and will work on understanding it :)
 #115  
09-17-08, 02:10 PM
Richard Heathfield
arnuld said:

>> This is from MAN page itself:

>
> The calloc() function shall allocate unused space for an
> array
> of nelem elements each of whose size in bytes is elsize. The
> space shall be initialized to all bits 0.
>
> Array elements in your example are of type V, not *V. This is what
> confusing me.


V isn't a type. It's a pointer. Let them be of type T, instead. Okay?

Yes, V points to n elements, each of which is sizeof *V bytes in size. What
is *V? It's the thing pointed to by V. What's sizeof *V, then? Right - the
size of one of these things. It's hard to make this any easier.

>> The perror call. The place to display this kind of error message is in
>> the application code, which in your case is basically main().

>
> so we *always* use perror() in main() ?


We do? I hardly ever use it at all. But if I do use it, I don't bury it in
a library function.

>> .... SNIP.....

>
>> int main(void)
>> {
>> char *word = NULL;
>> while(get_single_word(&word) == 0 && word[0] != '\0') {
>> printf("[%s]\n", word);
>> free(word);
>> }

>
> we calloc the memory in some other function while freeing it in some
> other. Thats really strange.


Why is that strange? You want to build these things into a list, don't you,
in due course? The way you seem to be wanting to do this, your list will
only ever have one entry in it at any given time.

allocate space for "Now"
add "Now" to list
remove "Now" from list
free "Now"
allocate space for "is"
add "is" to list
remove "is" from list
free "is"

etc, which is just stupid.

I am not saying its wrong. I am saying its
> feels strange for the programmers who has used languages like Lisp,
> Python, Ruby and C++ (only using Std. Lib. like string and vector)


Are you claiming Lisp can only do lists one element long?
 #116  
09-17-08, 02:25 PM
Nick Keighley
On 17 Sep, 08:45, Richard Heathfield <r...@see.sig.invalid> wrote:
> Nick Keighley said:
> > On 17 Sep, 07:59, arnuld <sunr...@invalid.address> wrote:


> >> ..aye.... , so lets learn the practical aspects like error-recovery too.
> >> I don't like academic solutions BTW

>
> > when, exactly, did "academic" become a pejorative term?

>
> What makes you think he's using it pejoratively? He's just saying he
> doesn't like academic solutions. I don't like salmon, but that doesn't
> mean I consider "salmon" to be a pejorative term.


but it is often used that way.

Are the algorithms in Knuth academic? Does arnuld dislike them?


> > "Yes it works in practice - but does it work in theory?"

>
> > "There is nothing as practical as a good theory."

>
> This isn't about theory vs practice, but about good practice vs indifferent
> practice.


and good practice often has a sound theoretical base.
 #117  
09-17-08, 02:55 PM
arnuld
> On Wed, 17 Sep 2008 13:10:14 +0000, Richard Heathfield wrote:

> V isn't a type. It's a pointer. Let them be of type T, instead. Okay?
>
> Yes, V points to n elements, each of which is sizeof *V bytes in size. What
> is *V? It's the thing pointed to by V. What's sizeof *V, then? Right - the
> size of one of these things. It's hard to make this any easier.


I should have been more clear. Take a look st this:

char* T;
T = calloc( 10, sizeof(char));

while your expression is:

char* T;
T = calloc( 10, sizeof(*T));


Thats what I am talking about, I am looking for a place to store N
characters, not 10 pointers to pointers (in our original program). So why
create space for char** when we want to store char(s) in them. This is my
original question about calloc/malloc/realloc


> Are you claiming Lisp can only do lists one element long?



No, I am claiming that we never ever think of managing memory in Lisp :)
 #118  
09-17-08, 03:05 PM
Jean-Marc Bourguet
arnuld <sunrise> writes:

> No, I am claiming that we never ever think of managing memory in Lisp :)


I do. Less than in C, but I do.

Yours,
 #119  
09-17-08, 03:06 PM
James Kuyper
Nick Keighley wrote:
> On 17 Sep, 08:45, Richard Heathfield <r...@see.sig.invalid> wrote:
>> Nick Keighley said:
>>> On 17 Sep, 07:59, arnuld <sunr...@invalid.address> wrote:

>
>>>> ..aye.... , so lets learn the practical aspects like error-recovery too.
>>>> I don't like academic solutions BTW
>>> when, exactly, did "academic" become a pejorative term?

>> What makes you think he's using it pejoratively? He's just saying he
>> doesn't like academic solutions. I don't like salmon, but that doesn't
>> mean I consider "salmon" to be a pejorative term.

>
> but it is often used that way.


In context, arnuld was using the term "academic" in reference to
Richard's statement 'If this is a mere learning exercise and the
learning task is not error recovery, then yes, by all means bomb out.
That's the "student solution"...'. I think that the contextual meaning
was clearly pejorative ("mere learning exercise"), whether or not he
meant it to be more generally pejorative.
 #120  
09-17-08, 03:19 PM
Ben Bacarisse
arnuld <sunrise> writes:

>> I should have been more clear. Take a look st this:

>
> char* T;
> T = calloc( 10, sizeof(char));
>
> while your expression is:
>
> char* T;
> T = calloc( 10, sizeof(*T));
>> Thats what I am talking about, I am looking for a place to store N

> characters, not 10 pointers to pointers (in our original program).


And there is the problem (in your understanding). sizeof (*T) is 1.
*T is the first char pointer to by T. It is not in any way a
pointer. It is a way to denote a single char.

It would have been slightly clearer, I think, if you had not used the
name T since Richard was using T as the type of the things pointed to
by V. Is this any clearer:

char *ptr;
ptr = calloc(10, sizeof *ptr);

?

Similar Threads
Best way to input from stdin?

I'm writing a program that supports input from stdin. To be able to do that I tend to rely on a simple loop that tests the return of fgets(), such as the following...

How to accept input from stdin?

Hi, I try to make a wrapper around an existing program, which would behave exactly the same as the original one. But my following attempt was failed. Would you pleaes let me...

Input using stdin

How can I give input to a program using STDIN Suppose I want the program to take the value x=10 On some other site i found it as STDIN.read,but its not working.

getting input from stdin

Hi Im new to unix scripting and now Im trying to get user input from stdin and this is what I did echo "enter your name: " read name and it will run with the pointer to...

Checking available input on stdin

I know this has probably come up frequently, but couldn't find a satisfactory reference... I have some code which needs to read from stdin but must not block waiting for...


All times are GMT. The time now is 07:40 AM. | Privacy Policy