473,387 Members | 1,572 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Dynamic C String Problem

Dear all,

Using the conio implementation i wanted to create a dynamic string,
whereby its size would be determined after each keyboard hit; in other
words, i don't want to ask the user to specify the the size, but
rather keep him/her typing and after each keyboard hit, the function
getch() determines whether he/she entered the ENTER key to end the
process; otherwise, increases the dynamic size or also decreases it if
the back key was hit.

For now, here is my code and I'm having
an issue; namely, the string adds extra characters not inputed and by
long strings, it doesn't hold all characters. Here is my code and
thank you in advance:

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

#define BACK_KEY 8
#define ENTER_KEY 13

typedef char * chptr;

int main (void){
int index = 0, x, y;
char input;
chptr buffer = (chptr) calloc (1 , sizeof(char));
printf("String Input =");
do{
input = getch();
if (input != ENTER_KEY && input != BACK_KEY){
buffer[index] = input;
buffer = (chptr) realloc (buffer, ++index);
printf("%c", input);
}
else
if (input == ENTER_KEY)
buffer = (chptr) realloc (buffer,--index);
else
if (index 0){
buffer[index-1] = '\0';
buffer = (chptr) realloc (buffer, --index);
x = wherex() - 1; y = wherey();
gotoxy(x,y); clreol();
}
}while(input != ENTER_KEY);
printf("\nString Output: %s\n", buffer);
if (buffer != NULL) free(buffer);
getch();
return EXIT_SUCCESS;
}

Nov 5 '06 #1
13 2000
coosa wrote:
i wanted to create a dynamic string,
in other words, i don't want to ask the user to specify the the size,
This is how I do that:

/* BEGIN line_to_string.c */

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

struct list_node {
struct list_node *next;
void *data;
};

int line_to_string(FILE *fp, char **line, size_t *size);
void list_free(struct list_node *node, void (*free_data)(void *));
void list_fputs(FILE *stream, struct list_node *node);
struct list_node *string_node(struct list_node **head,
struct list_node *tail,
char *data);

int main(void)
{
struct list_node *head, *tail;
int rc;
char *buff_ptr;
size_t buff_size;
long unsigned line_count;

puts(
"\nThis program makes and prints a list of all the lines\n"
"of text entered from standard input.\n"
"Just hit the Enter key to end,\n"
"or enter any line of characters to continue."
);
tail = head = NULL;
line_count = 0;
buff_size = 0;
buff_ptr = NULL;
while ((rc = line_to_string(stdin, &buff_ptr, &buff_size)) 1) {
++line_count;
tail = string_node(&head, tail, buff_ptr);
if (tail == NULL) {
break;
}
puts(
"\nJust hit the Enter key to end,\n"
"or enter any other line of characters to continue."
);
}
switch (rc) {
case EOF:
if (buff_ptr != NULL && strlen(buff_ptr) 0) {
puts("rc equals EOF\nThe string in buff_ptr is:");
puts(buff_ptr);
++line_count;
tail = string_node(&head, tail, buff_ptr);
}
break;
case 0:
puts("realloc returned a null pointer value");
if (buff_size 1) {
puts("rc equals 0\nThe string in buff_ptr is:");
puts(buff_ptr);
++line_count;
tail = string_node(&head, tail, buff_ptr);
}
break;
default:
break;
}
if (line_count != 0 && tail == NULL) {
puts("Node allocation failed.");
puts("The last line entered didn't make it onto the list:");
puts(buff_ptr);
}
free(buff_ptr);
puts("\nThe line buffer has been freed.\n");
printf("%lu lines of text were entered.\n", line_count);
puts("They are:\n");
list_fputs(stdout, head);
list_free(head, free);
puts("\nThe list has been freed.\n");
return 0;
}

int line_to_string(FILE *fp, char **line, size_t *size)
{
int rc;
void *p;
size_t count;

count = 0;
while ((rc = getc(fp)) != EOF) {
++count;
if (count + 2 *size) {
p = realloc(*line, count + 2);
if (p == NULL) {
if (*size count) {
(*line)[count] = '\0';
(*line)[count - 1] = (char)rc;
} else {
ungetc(rc, fp);
}
count = 0;
break;
}
*line = p;
*size = count + 2;
}
if (rc == '\n') {
(*line)[count - 1] = '\0';
break;
}
(*line)[count - 1] = (char)rc;
}
if (rc != EOF) {
rc = count INT_MAX ? INT_MAX : count;
} else {
if (*size count) {
(*line)[count] = '\0';
}
}
return rc;
}

void list_free(struct list_node *node, void (*free_data)(void *))
{
struct list_node *next_node;

while (node != NULL) {
next_node = node -next;
free_data(node -data);
free(node);
node = next_node;
}
}

void list_fputs(FILE *stream, struct list_node *node)
{
while (node != NULL) {
fputs(node -data, stream);
putc('\n', stream);
node = node -next;
}
}

struct list_node *string_node(struct list_node **head,
struct list_node *tail,
char *data)
{
struct list_node *node;

node = malloc(sizeof *node);
if (node != NULL) {
node -next = NULL;
node -data = malloc(strlen(data) + 1);
if (node -data != NULL) {
if (*head == NULL) {
*head = node;
} else {
tail -next = node;
}
strcpy(node -data, data);
} else {
free(node);
node = NULL;
}
}
return node;
}

/* END line_to_string.c */
--
pete
Nov 5 '06 #2
coosa wrote:
Dear all,

Using the conio implementation i wanted to create a dynamic string,
whereby its size would be determined after each keyboard hit; in other
words, i don't want to ask the user to specify the the size, but
rather keep him/her typing and after each keyboard hit, the function
getch() determines whether he/she entered the ENTER key to end the
process; otherwise, increases the dynamic size or also decreases it if
the back key was hit.

For now, here is my code and I'm having
an issue; namely, the string adds extra characters not inputed and by
long strings, it doesn't hold all characters. Here is my code and
thank you in advance:

#include <stdio.h>
#include <stdlib.h>
#include <conio2.h>
This is a non-standard header, and should not be used in this
newsgroup.
#define BACK_KEY 8
#define ENTER_KEY 13

typedef char * chptr;
There is really no need for such a simple typedef. Much better
to just use 'char *' where needed.
int main (void){
int index = 0, x, y;
char input;
chptr buffer = (chptr) calloc (1 , sizeof(char));
You should not cast the value returned from malloc and family.
Also, sizeof char is by definition 1.

The approach you are taking of allocating memory a byte at a time
is wasteful. You should start out with a buffer big enough to
hold the expected amount of data. If you need more space, then
realloc another big block, not just an extra byte. There is also
no point in shrinking your buffer character by character.
printf("String Input =");
This will not necessarily appear; you should fflush() stdout to
make sure it does.
do{
input = getch();
if (input != ENTER_KEY && input != BACK_KEY){
buffer[index] = input;
buffer = (chptr) realloc (buffer, ++index);
index started out as 0, and you increment it here. Your new
block of memory now has a size of 1, just like it did before.

Also, if realloc() fails, you leak the previous memory pointed to
by buffer. You need to store the return value of realloc() in a
temporary pointer variable, test that for nullity, and if
realloc() succeeds, free the old buffer.
printf("%c", input);
}
else
if (input == ENTER_KEY)
buffer = (chptr) realloc (buffer,--index);
else
if (index 0){
buffer[index-1] = '\0';
buffer = (chptr) realloc (buffer, --index);
x = wherex() - 1; y = wherey();
gotoxy(x,y); clreol();
}
}while(input != ENTER_KEY);
printf("\nString Output: %s\n", buffer);
You never terminated your string with a '\0'.
if (buffer != NULL) free(buffer);
getch();
return EXIT_SUCCESS;
}

--
Thomas M. Sommers -- tm*@nj.net -- AB2SB

Nov 5 '06 #3

T.M. Sommers wrote:
coosa wrote:
Dear all,

Using the conio implementation i wanted to create a dynamic string,
whereby its size would be determined after each keyboard hit; in other
words, i don't want to ask the user to specify the the size, but
rather keep him/her typing and after each keyboard hit, the function
getch() determines whether he/she entered the ENTER key to end the
process; otherwise, increases the dynamic size or also decreases it if
the back key was hit.

For now, here is my code and I'm having
an issue; namely, the string adds extra characters not inputed and by
long strings, it doesn't hold all characters. Here is my code and
thank you in advance:

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

This is a non-standard header, and should not be used in this
newsgroup.
#define BACK_KEY 8
#define ENTER_KEY 13

typedef char * chptr;

There is really no need for such a simple typedef. Much better
to just use 'char *' where needed.
int main (void){
int index = 0, x, y;
char input;
chptr buffer = (chptr) calloc (1 , sizeof(char));

You should not cast the value returned from malloc and family.
Also, sizeof char is by definition 1.

The approach you are taking of allocating memory a byte at a time
is wasteful. You should start out with a buffer big enough to
hold the expected amount of data. If you need more space, then
realloc another big block, not just an extra byte. There is also
no point in shrinking your buffer character by character.
printf("String Input =");

This will not necessarily appear; you should fflush() stdout to
make sure it does.
do{
input = getch();
if (input != ENTER_KEY && input != BACK_KEY){
buffer[index] = input;
buffer = (chptr) realloc (buffer, ++index);

index started out as 0, and you increment it here. Your new
block of memory now has a size of 1, just like it did before.
Is it? what about ++index? it's a prefix operator, so it should
increment before the allocation
>
Also, if realloc() fails, you leak the previous memory pointed to
by buffer. You need to store the return value of realloc() in a
temporary pointer variable, test that for nullity, and if
realloc() succeeds, free the old buffer.
printf("%c", input);
}
else
if (input == ENTER_KEY)
buffer = (chptr) realloc (buffer,--index);
else
if (index 0){
buffer[index-1] = '\0';
buffer = (chptr) realloc (buffer, --index);
x = wherex() - 1; y = wherey();
gotoxy(x,y); clreol();
}
}while(input != ENTER_KEY);
printf("\nString Output: %s\n", buffer);

You never terminated your string with a '\0'.
if (buffer != NULL) free(buffer);
getch();
return EXIT_SUCCESS;
}


--
Thomas M. Sommers -- tm*@nj.net -- AB2SB
Nov 5 '06 #4
coosa wrote:
T.M. Sommers wrote:
>>coosa wrote:
>>>int main (void){
int index = 0, x, y;
....
>> buffer = (chptr) realloc (buffer, ++index);

index started out as 0, and you increment it here. Your new
block of memory now has a size of 1, just like it did before.

Is it? what about ++index? it's a prefix operator, so it should
increment before the allocation
Right. Think about what happens the first time through the loop.

--
Thomas M. Sommers -- tm*@nj.net -- AB2SB

Nov 5 '06 #5
coosa wrote:
>
Using the conio implementation i wanted to create a dynamic string,
whereby its size would be determined after each keyboard hit; in
other words, i don't want to ask the user to specify the the size,
but rather keep him/her typing and after each keyboard hit, the
function getch() determines whether he/she entered the ENTER key to
end the process; otherwise, increases the dynamic size or also
decreases it if the back key was hit.

For now, here is my code and I'm having an issue; namely, the
string adds extra characters not inputed and by long strings, it
doesn't hold all characters. Here is my code and thank you in
advance:
conio and getch are non-standard, and not needed for your
purposes. I have published a standard C routine ggets() which will
do what you want, and is totally portable. See:

<http://cbfalconer.home.att.net/download/>

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Nov 5 '06 #6
On Sun, 2006-11-05 at 10:09 -0800, coosa wrote:
Dear all,

Using the conio implementation i wanted to create a dynamic string,
whereby its size would be determined after each keyboard hit; in other
words, i don't want to ask the user to specify the the size, but
rather keep him/her typing and after each keyboard hit, the function
getch() determines whether he/she entered the ENTER key to end the
process; otherwise, increases the dynamic size or also decreases it if
the back key was hit.
How about you /don't/ use conio.h, and use getchar() for keyboard
input instead, at least when posting on this group? You will get
much more help if you keep your code within the limits of Standard
C.
For now, here is my code and I'm having
an issue; namely, the string adds extra characters not inputed and by
long strings, it doesn't hold all characters. Here is my code and
thank you in advance:

#include <stdio.h>
#include <stdlib.h>
#include <conio2.h>
See my above comment, but also, what is "conio2.h"? I've never heard
of that one.
>
#define BACK_KEY 8
#define ENTER_KEY 13
Better: use '\b' and '\n'. See how nice the C Standard has been in
providing these things?
typedef char * chptr;
Don't do that. It's just irritating and confusing. Use char *
in your code.
int main (void){
int index = 0, x, y;
char input;
chptr buffer = (chptr) calloc (1 , sizeof(char));
1. Why calloc?
2. Don't cast the result of *alloc(). It's dangerous.
3. sizeof(type) is almost always not what you want. Use sizeof object
(which in this case would be, sizeof *buffer).
4. sizeof(char) is always 1, so in this case you can ignore #3.
5. Don't start with an inital buffer of 1. CB Falconer uses 112 in
his ggets() function, which I recommend you look at (and perhaps use in
place of your code; it is public domain).

So,
char *buffer = malloc(112);
printf("String Input =");
do{
input = getch();
>From here on I'm assuming that getch() inputs characters without
outputting them to the screen, since that's what you seem to want.
I have no idea if that's what it actually does, though.
if (input != ENTER_KEY && input != BACK_KEY){
buffer[index] = input;
buffer = (chptr) realloc (buffer, ++index);
Don't reallocate 1 more byte. Allocate 2 times as much as you had,
or maybe 4/3 as much. Also, see my above comments on *alloc() usage.

[snip remaining code]
Seriously, take a look at how ggets() is implemented. It is
completely Standard C (there's no reason not to be within those
limits in this case), and is done very well. It is one this page:
http://cbfalconer.home.att.net/download/

--
Andrew Poelstra <http://www.wpsoftware.net>
For email, use 'apoelstra' at the above site.
"You're only smart on the outside." -anon.

Nov 6 '06 #7
Andrew Poelstra wrote:
On Sun, 2006-11-05 at 10:09 -0800, coosa wrote:
Dear all,

Using the conio implementation i wanted to create a dynamic string,
whereby its size would be determined after each keyboard hit; in other
words, i don't want to ask the user to specify the the size, but
rather keep him/her typing and after each keyboard hit, the function
getch() determines whether he/she entered the ENTER key to end the
process; otherwise, increases the dynamic size or also decreases it if
the back key was hit.

How about you /don't/ use conio.h, and use getchar() for keyboard
input instead, at least when posting on this group? You will get
much more help if you keep your code within the limits of Standard
C.
Of Course i would prefer a standard portable code instead of conio,
conio2 is a re-implementation and is provided as a devpack using Dev
C++ for Windows.
>
For now, here is my code and I'm having
an issue; namely, the string adds extra characters not inputed and by
long strings, it doesn't hold all characters. Here is my code and
thank you in advance:

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

See my above comment, but also, what is "conio2.h"? I've never heard
of that one.

#define BACK_KEY 8
#define ENTER_KEY 13

Better: use '\b' and '\n'. See how nice the C Standard has been in
providing these things?
typedef char * chptr;

Don't do that. It's just irritating and confusing. Use char *
in your code.
int main (void){
int index = 0, x, y;
char input;
chptr buffer = (chptr) calloc (1 , sizeof(char));

1. Why calloc?
I read that calloc will initialize the size to zero in contradiction to
malloc; i honeslty learned C once and through implementation didn't get
yet clearly the difference between them.
2. Don't cast the result of *alloc(). It's dangerous.
Well, through all the examples i read so far in lecture notes and books
as well in the web used a casting :-) so don't blame me! :-D
3. sizeof(type) is almost always not what you want. Use sizeof object
(which in this case would be, sizeof *buffer).
4. sizeof(char) is always 1, so in this case you can ignore #3.
5. Don't start with an inital buffer of 1. CB Falconer uses 112 in
his ggets() function, which I recommend you look at (and perhaps use in
place of your code; it is public domain).
The purpose of my code is actually to produce a dynamic approach of
allocating EXACTLY what a data type requires, not more and not less. It
might sound silly to only allocate an initial size of 1 Byte, but
considering a country code that consists of only two character such as
'CA' for Canada, 'MY' for Malaysia and so third and so fourth, wouldn't
it be allocating 128 Bytes a waste to allocate such unnecessary memory
for such a variable that needs of 2 Bytes?
>
So,
char *buffer = malloc(112);
printf("String Input =");
do{
input = getch();
From here on I'm assuming that getch() inputs characters without
outputting them to the screen, since that's what you seem to want.
I have no idea if that's what it actually does, though.
if (input != ENTER_KEY && input != BACK_KEY){
buffer[index] = input;
buffer = (chptr) realloc (buffer, ++index);

Don't reallocate 1 more byte. Allocate 2 times as much as you had,
or maybe 4/3 as much. Also, see my above comments on *alloc() usage.

[snip remaining code]
Seriously, take a look at how ggets() is implemented. It is
completely Standard C (there's no reason not to be within those
limits in this case), and is done very well. It is one this page:
http://cbfalconer.home.att.net/download/

--
Andrew Poelstra <http://www.wpsoftware.net>
For email, use 'apoelstra' at the above site.
"You're only smart on the outside." -anon.
Nov 9 '06 #8

Andrew Poelstra wrote:
On Sun, 2006-11-05 at 10:09 -0800, coosa wrote:
Dear all,

Using the conio implementation i wanted to create a dynamic string,
whereby its size would be determined after each keyboard hit; in other
words, i don't want to ask the user to specify the the size, but
rather keep him/her typing and after each keyboard hit, the function
getch() determines whether he/she entered the ENTER key to end the
process; otherwise, increases the dynamic size or also decreases it if
the back key was hit.

How about you /don't/ use conio.h, and use getchar() for keyboard
input instead, at least when posting on this group? You will get
much more help if you keep your code within the limits of Standard
C.
Of Course, I would prefer a standard portable code instead of conio,
conio2 is a re-implementation and is provided as a devpack using Dev
C++ for Windows.
>
For now, here is my code and I'm having
an issue; namely, the string adds extra characters not inputed and by
long strings, it doesn't hold all characters. Here is my code and
thank you in advance:

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

See my above comment, but also, what is "conio2.h"? I've never heard
of that one.

#define BACK_KEY 8
#define ENTER_KEY 13

Better: use '\b' and '\n'. See how nice the C Standard has been in
providing these things?
typedef char * chptr;

Don't do that. It's just irritating and confusing. Use char *
in your code.
int main (void){
int index = 0, x, y;
char input;
chptr buffer = (chptr) calloc (1 , sizeof(char));

1. Why calloc?
I read that calloc will initialize the size to zero in contradiction to
malloc; i honeslty learned C once and through implementation didn't get
yet clearly the difference between them.
2. Don't cast the result of *alloc(). It's dangerous.
Well, through all the examples i read so far in lecture notes and books
as well in the web used a casting :-) so don't blame me! :-D
3. sizeof(type) is almost always not what you want. Use sizeof object
(which in this case would be, sizeof *buffer).
4. sizeof(char) is always 1, so in this case you can ignore #3.
5. Don't start with an inital buffer of 1. CB Falconer uses 112 in
his ggets() function, which I recommend you look at (and perhaps use in
place of your code; it is public domain).
The purpose of my code is actually to produce a dynamic approach of
allocating EXACTLY what a data type requires, not more and not less. It
might sound silly to only allocate an initial size of 1 Byte, but
considering a country code that consists of only two characters only
such as 'CA' for Canada, 'MY' for Malaysia and so third and so fourth,
wouldn't be allocating 128 Bytes a waste to allocate such unnecessary
memory for such a variable that needs of 2 Bytes?
>
So,
char *buffer = malloc(112);
printf("String Input =");
do{
input = getch();
From here on I'm assuming that getch() inputs characters without
outputting them to the screen, since that's what you seem to want.
I have no idea if that's what it actually does, though.
if (input != ENTER_KEY && input != BACK_KEY){
buffer[index] = input;
buffer = (chptr) realloc (buffer, ++index);

Don't reallocate 1 more byte. Allocate 2 times as much as you had,
or maybe 4/3 as much. Also, see my above comments on *alloc() usage.
>
[snip remaining code]
Seriously, take a look at how ggets() is implemented. It is
completely Standard C (there's no reason not to be within those
limits in this case), and is done very well. It is one this page:
http://cbfalconer.home.att.net/download/

--
Andrew Poelstra <http://www.wpsoftware.net>
For email, use 'apoelstra' at the above site.
"You're only smart on the outside." -anon.
Nov 9 '06 #9
coosa said:

<snip>
>
I read that calloc will initialize the size to zero in contradiction to
malloc;
Close. It'll initialise to all-bits-zero, which needn't mean "a value of
zero" for non-integer types (although it often does end up that way).
>2. Don't cast the result of *alloc(). It's dangerous.

Well, through all the examples i read so far in lecture notes and books
as well in the web used a casting :-) so don't blame me! :-D
You can't be blamed for being misinformed, but the cast - whilst not
actually incorrect - is unnecessary and can hide a serious bug. See
http://www.cpax.org.uk/prg/writings/casting.php for a fuller explanation.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: normal service will be restored as soon as possible. Please do not
adjust your email clients.
Nov 9 '06 #10
coosa wrote:
Andrew Poelstra wrote:
>On Sun, 2006-11-05 at 10:09 -0800, coosa wrote:
>>Dear all,

Using the conio implementation i wanted to create a dynamic string,
whereby its size would be determined after each keyboard hit; in other
words, i don't want to ask the user to specify the the size, but
rather keep him/her typing and after each keyboard hit, the function
getch() determines whether he/she entered the ENTER key to end the
process; otherwise, increases the dynamic size or also decreases it if
the back key was hit.
How about you /don't/ use conio.h, and use getchar() for keyboard
input instead, at least when posting on this group? You will get
much more help if you keep your code within the limits of Standard
C.

Of Course, I would prefer a standard portable code instead of conio,
conio2 is a re-implementation and is provided as a devpack using Dev
C++ for Windows.
Then use portable standard functions. Andrew was even kind enough to
point you in the right direction.

<snip>
>> chptr buffer = (chptr) calloc (1 , sizeof(char));
1. Why calloc?

I read that calloc will initialize the size to zero in contradiction to
malloc; i honeslty learned C once and through implementation didn't get
yet clearly the difference between them.
Ah, but to you really need the entire buffer cleared?
>2. Don't cast the result of *alloc(). It's dangerous.

Well, through all the examples i read so far in lecture notes and books
as well in the web used a casting :-) so don't blame me! :-D
Now you know better. Countless people drive dangerously, are you going
to drive dangerously just because many others do?
>3. sizeof(type) is almost always not what you want. Use sizeof object
(which in this case would be, sizeof *buffer).
4. sizeof(char) is always 1, so in this case you can ignore #3.
5. Don't start with an inital buffer of 1. CB Falconer uses 112 in
his ggets() function, which I recommend you look at (and perhaps use in
place of your code; it is public domain).

The purpose of my code is actually to produce a dynamic approach of
allocating EXACTLY what a data type requires, not more and not less. It
might sound silly to only allocate an initial size of 1 Byte, but
considering a country code that consists of only two characters only
such as 'CA' for Canada, 'MY' for Malaysia and so third and so fourth,
wouldn't be allocating 128 Bytes a waste to allocate such unnecessary
memory for such a variable that needs of 2 Bytes?
If you know there really is a small finite limit to the data it is
better to use a small finite fixed size buffer and input routines that
take the size of the buffer and, if the user enters too long a string,
do not overflow but instead flag back to the calling routine.

*alloc functions have a significant overhead and growing buffers one
byte at a time is likely to exacerbate the problems. Think about all the
housekeeping and also look up "memory fragmentation".
>So,
<snip>

Also, please snip text you are not replying to as I have done here, it
keeps posts down to a reasonable size. Of course, leave in *enough*
context for your post to stand on its own.
--
Flash Gordon
Nov 9 '06 #11

Flash Gordon wrote:
coosa wrote:
Andrew Poelstra wrote:
On Sun, 2006-11-05 at 10:09 -0800, coosa wrote:
Dear all,

Using the conio implementation i wanted to create a dynamic string,
whereby its size would be determined after each keyboard hit; in other
words, i don't want to ask the user to specify the the size, but
rather keep him/her typing and after each keyboard hit, the function
getch() determines whether he/she entered the ENTER key to end the
process; otherwise, increases the dynamic size or also decreases it if
the back key was hit.

How about you /don't/ use conio.h, and use getchar() for keyboard
input instead, at least when posting on this group? You will get
much more help if you keep your code within the limits of Standard
C.
Of Course, I would prefer a standard portable code instead of conio,
conio2 is a re-implementation and is provided as a devpack using Dev
C++ for Windows.

Then use portable standard functions. Andrew was even kind enough to
point you in the right direction.

<snip>
> chptr buffer = (chptr) calloc (1 , sizeof(char));
1. Why calloc?
I read that calloc will initialize the size to zero in contradiction to
malloc; i honeslty learned C once and through implementation didn't get
yet clearly the difference between them.

Ah, but to you really need the entire buffer cleared?
2. Don't cast the result of *alloc(). It's dangerous.
Well, through all the examples i read so far in lecture notes and books
as well in the web used a casting :-) so don't blame me! :-D

Now you know better. Countless people drive dangerously, are you going
to drive dangerously just because many others do?
3. sizeof(type) is almost always not what you want. Use sizeof object
(which in this case would be, sizeof *buffer).
4. sizeof(char) is always 1, so in this case you can ignore #3.
5. Don't start with an inital buffer of 1. CB Falconer uses 112 in
his ggets() function, which I recommend you look at (and perhaps use in
place of your code; it is public domain).
The purpose of my code is actually to produce a dynamic approach of
allocating EXACTLY what a data type requires, not more and not less. It
might sound silly to only allocate an initial size of 1 Byte, but
considering a country code that consists of only two characters only
such as 'CA' for Canada, 'MY' for Malaysia and so third and so fourth,
wouldn't be allocating 128 Bytes a waste to allocate such unnecessary
memory for such a variable that needs of 2 Bytes?

If you know there really is a small finite limit to the data it is
better to use a small finite fixed size buffer and input routines that
take the size of the buffer and, if the user enters too long a string,
do not overflow but instead flag back to the calling routine.

*alloc functions have a significant overhead and growing buffers one
byte at a time is likely to exacerbate the problems. Think about all the
housekeeping and also look up "memory fragmentation".
<snip>

Well some thing still bothers me; in C++, "Shrink to Fit" well known
for the STL's Sequence Containers including the Standard C++ String
Class. I would go along with your method and do it the way you
recommended, but I'll end up shrinking extra space to fit the actual
length; either way, my old way byte by byte or this way, the result is
the same.
>
So,

<snip>

Also, please snip text you are not replying to as I have done here, it
keeps posts down to a reasonable size. Of course, leave in *enough*
context for your post to stand on its own.
--
Flash Gordon
Nov 9 '06 #12
On 2006-11-09, coosa <co*****@gmail.comwrote:
Andrew Poelstra wrote:
>On Sun, 2006-11-05 at 10:09 -0800, coosa wrote:
int main (void){
int index = 0, x, y;
char input;
chptr buffer = (chptr) calloc (1 , sizeof(char));

1. Why calloc?

I read that calloc will initialize the size to zero in contradiction to
malloc; i honeslty learned C once and through implementation didn't get
yet clearly the difference between them.
>2. Don't cast the result of *alloc(). It's dangerous.

Well, through all the examples i read so far in lecture notes and books
as well in the web used a casting :-) so don't blame me! :-D
Well, you came to the right place, then. This group will tell you
all sorts of things that the world teaches that are wrong. You
should tell your teacher not to cast malloc() if your lecture notes
really say to do so.

>3. sizeof(type) is almost always not what you want. Use sizeof object
(which in this case would be, sizeof *buffer).
4. sizeof(char) is always 1, so in this case you can ignore #3.
5. Don't start with an inital buffer of 1. CB Falconer uses 112 in
his ggets() function, which I recommend you look at (and perhaps use in
place of your code; it is public domain).

The purpose of my code is actually to produce a dynamic approach of
allocating EXACTLY what a data type requires, not more and not less. It
might sound silly to only allocate an initial size of 1 Byte, but
considering a country code that consists of only two character such as
'CA' for Canada, 'MY' for Malaysia and so third and so fourth, wouldn't
it be allocating 128 Bytes a waste to allocate such unnecessary memory
for such a variable that needs of 2 Bytes?
Not necessarily. The internal implementation of malloc() may very well
always allocate 16 bytes, or some other large number, simply to justify
the bookkeeping required to allocate memory. So, you're wasting space
by /not/ guaranteeing yourself access to all that memory.
>Seriously, take a look at how ggets() is implemented. It is
completely Standard C (there's no reason not to be within those
limits in this case), and is done very well. It is one this page:
http://cbfalconer.home.att.net/download/
Nov 9 '06 #13
coosa wrote:
Andrew Poelstra wrote:
<snipped>
I read that calloc will initialize the size to zero in contradiction to
You perhaps mean "initialise the buffer to all zeros"?
2. Don't cast the result of *alloc(). It's dangerous.

Well, through all the examples i read so far in lecture notes and books
as well in the web used a casting :-) so don't blame me! :-D
Well, you've had a stroke of luck running into this newsgroup
then :-)

All those examples in lecture notes and books as well as in(sic)
the web were either
a) Wrong
OR
b) C++ examples, not C examples.

goose,

Nov 10 '06 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: K | last post by:
I have found a script online that I want to use (I am new to PHP). It creates dynamic images based on the text that you pass it. However, no matter how I try, I can't get anything other than a...
3
by: Stephen Gennard | last post by:
Hello, I having a problem dynamically invoking a static method that takes a reference to a SByte*. If I do it directly it works just fine. Anyone any ideas why? I have include a example...
6
by: MikeY | last post by:
Hi Everyone, Does anyone know where I can get my hands on a sample with source code of a simple dynamic button control in C# Windows form. I am looking for a sample that uses a class library...
1
by: sleigh | last post by:
Hello, I'm building a web application that will build a dynamic form based upon questions in a database. This form will have several different sections that consist of a panel containing one to...
1
by: russ | last post by:
Hi all, Here's a problem I'm having with a dynamic table. Following the guidelines here (http://www.codeproject.com/aspnet/dynamiccontrols.asp), which make perfect sense. The problem is that...
8
by: Sandy Pittendrigh | last post by:
I have a how-to-do-it manual like site, related to fishing. I want to add a new interactive question/comment feature to each instructional page on the site. I want (registered) users to be able...
23
by: sandy | last post by:
I need (okay, I want) to make a dynamic array of my class 'Directory', within my class Directory (Can you already smell disaster?) Each Directory can have subdirectories so I thought to put these...
9
by: Tarscher | last post by:
hi all, I have this seemingly simple problem. I have lost a lot of time on it though. When a user selects a value from a dropdownlist (static control) a dynamic control is generated. I have...
0
by: tickle | last post by:
Need to convert this PL/SQL script to Dynamic SQL Method 2 * copybook - celg02u3.sql SIR 24265 * * updates dt_deny for all rows in * * ...
3
by: vainstah | last post by:
Hello Guys and Galls, To start off, I have reached the solution I was looking for, but I would like comments and feedback on the solution I have reached and tips/tricks on making it more elegant....
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.