|
#106
|
|
|
|
|
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
|
|
|
|
|
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
|
|
|
|
|
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
|
|
|
|
|
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
|
|
|
|
|
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
|
|
|
|
|
> 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
|
|
|
|
|
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
|
|
|
|
|
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
|
|
|
|
|
> 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
|
|
|
|
|
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
|
|
|
|
|
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
|
|
|
|
|
> 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
|
|
|
|
|
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
|
|
|
|
|
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
|
|
|
|
|
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
|