malloc for strings(beginner)

F

fool

Dear group,
if I want to allocate a string with a help of malloc then, shall
I use the following in a loop?
char *s;
s = malloc(strlen(s)+1);
Any pointer reference is help full. I went through the K & R
book's chapter 5. But I am not able to get the answer.
 
M

Malcolm

fool said:
if I want to allocate a string with a help of malloc then, shall
I use the following in a loop?
char *s;
s = malloc(strlen(s)+1);
Any pointer reference is help full. I went through the K & R
book's chapter 5. But I am not able to get the answer.
At a guess, you are getting a string character by character, maybe from a
file.
What you want is this

char *s = 0;
char ch;
In N = 0;

do
{
ch = getacharacter();
N++;
s = realloc(s, N);
if(!s)
{
printf("Out of memory\n");
exit(EXIT_FAILURE);
}
s[N-1] = ch;
} while(ch != 0);

Modify the code if the string is termianted by newline (you will have to
replace the last charcter by a 0).
 
F

fool

fool said:
if I want to allocate a string with a help of malloc then, shall
I use the following in a loop?
char *s;
s = malloc(strlen(s)+1);
Any pointer reference is help full. I went through the K & R
book's chapter 5. But I am not able to get the answer.
At a guess, you are getting a string character by character, maybe from a
file.
What you want is this

char *s = 0;
char ch;
In N = 0;

do
{
ch = getacharacter();
N++;
s = realloc(s, N);
if(!s)
{
printf("Out of memory\n");
exit(EXIT_FAILURE);
}
s[N-1] = ch;
} while(ch != 0);

Modify the code if the string is termianted by newline (you will have to
replace the last charcter by a 0).

Am I correct with the following:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
char *s=0,ch, length;
int n,i;
do
{
fgets(s, sizeof s, stdin);
n++;
s = realloc(s, n);
if(!s)
exit(EXIT_FAILURE);
ch = *s++;
s[n-1] = ch;
length = strlen(s);
}while(ch != 0 );
for(i=0 ; i < length ; i++)
printf("%c\n",s);

return 0;
}

But gcc gives me a RT error.
 
R

Richard Heathfield

fool said:

Am I correct with the following:
No.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
char *s=0,ch, length;
int n,i;
do
{
fgets(s, sizeof s, stdin);

fgets requires a pointer to the first byte of memory it can use. But s is a
null pointer, so it doesn't point to any memory fgets can use. And the
second argument is supposed to say how many bytes of memory are available
at that address, to which the best answer you could reasonably give is: 0.

If you want to put stuff in a box, first get a box.
 
F

fool

fool said:



fgets requires a pointer to the first byte of memory it can use. But s is a
null pointer, so it doesn't point to any memory fgets can use. And the
second argument is supposed to say how many bytes of memory are available
at that address, to which the best answer you could reasonably give is: 0.

If you want to put stuff in a box, first get a box.

Me and my foolish brain!!

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
char *s=0,ch;
int n=0;
do
{
s = realloc(s, n);
if(!s)
exit(EXIT_FAILURE);
fgets(s, sizeof s, stdin);
n++;
ch = *s;
s[n-1] = ch;
printf("%s",s);
}while(ch != 0 && (*s) != '\0'); /* derefer s and till s
reaches '\0', correct?*/
return 0;
}
 
R

Richard Heathfield

fool said:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
char *s=0,ch;
int n=0;
do
{
s = realloc(s, n);
if(!s)
exit(EXIT_FAILURE);

This is not a good idea, but it'll do for now, except for the fact that
you're allocating ZERO bytes of memory on the first time round.
fgets(s, sizeof s, stdin);

sizeof s is wrong - s has type char *, so sizeof s is equivalent to
sizeof(char *), which isn't going to change any time soon. What you should
put here instead is the number of bytes available at the memory pointed to
by s - in this case, that would be n.

What if fgets failed? (It returns NULL if it encounters an error or an
end-of-file condition.) You need to detect this.
n++;
ch = *s;

copies first character of the input string to ch
s[n-1] = ch;

copies ch to the (n-1)th character of s - is that *really* what you want to
do? Especially if it overwrites your terminating null character (which
seems possible to me, although I admit I haven't read the code very
closely).
printf("%s",s);
}while(ch != 0 && (*s) != '\0'); /* derefer s and till s
reaches '\0', correct?*/

I think you need to take a step back and decide exactly what it is that
you're trying to do. Do you just want to read one string from stdin, or
many? Do you want to store one string, or many? What are you aiming for? If
you can answer this, perhaps we can help you better.
 
C

CBFalconer

fool said:
(e-mail address removed) says...

Me and my foolish brain!!

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
char *s=0,ch;
int n=0;
do
{
s = realloc(s, n);

No. The very first time you are allocating 0 bytes. This can't
hold anything. In addition reallocating for each input character
is an expensive operation.
if(!s)
exit(EXIT_FAILURE);
fgets(s, sizeof s, stdin);
n++;
ch = *s;
s[n-1] = ch;
printf("%s",s);
}while(ch != 0 && (*s) != '\0'); /* derefer s and till s
reaches '\0', correct?*/
return 0;
}

Now that you have tried various things out, download ggets and see
how I handle it. You can find the complete module at:

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

and it will probably be quite understandable after your efforts.
Most of the download is testing code and demonstration usage. It
then adds up to a whopping 11k byte download. the reallocation
strategy is optimized for the most usual usage of interactive
input, when very long input strings are extremely rare, and usually
require keyboard walking cats.

rjh has an alternative method. See readme.txt file in ggets.zip.
 
J

Joe Wright

fool said:
fool said:


fgets requires a pointer to the first byte of memory it can use. But s is a
null pointer, so it doesn't point to any memory fgets can use. And the
second argument is supposed to say how many bytes of memory are available
at that address, to which the best answer you could reasonably give is: 0.

If you want to put stuff in a box, first get a box.

Me and my foolish brain!!

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
char *s=0,ch;
int n=0;
do
{
s = realloc(s, n);
if(!s)
exit(EXIT_FAILURE);
fgets(s, sizeof s, stdin);
n++;
ch = *s;
s[n-1] = ch;
printf("%s",s);
}while(ch != 0 && (*s) != '\0'); /* derefer s and till s
reaches '\0', correct?*/
return 0;
}

Several things I don't understand about your code but here's mine.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char line[80];
char *t, *s = NULL;
int n, len = 0;
while (fgets(line, sizeof line, stdin)) {
n = strlen(line);
t = realloc(s, len + n+1);
if (!t) puts("alloc failure."), exit(EXIT_FAILURE);
s = t;
strcpy(s+len, line);
len = strlen(s);
}
printf("%s", s);
return 0;
}
 
J

Jack Klein

comp.lang.c:

There is a serious error in your concept below.
Dear group,
if I want to allocate a string with a help of malloc then, shall
I use the following in a loop?
char *s;

Assuming that the definition of s, above, is inside a function, you
have created an uninitialized pointer, that is it does not contain the
address of one or more characters that belong to your program.
s = malloc(strlen(s)+1);

Passing the uninitialized pointer value 's' so strlen(), as you will
do on the first pass through the loop, produces undefined behavior and
quite possibly will cause your operating system to shut down your
program.
Any pointer reference is help full. I went through the K & R
book's chapter 5. But I am not able to get the answer.

I am not completely sure what it is you are trying to do. You have
not shown us enough of your code. The correction is different if you
are trying to allocate memory to copy an existing string, or if you
are trying to allocate memory for a string coming from an input
stream.

You should post again, and include the complete function that you are
trying to write, with an explanation of what it's inputs are and
exactly what you want the result to be.
 

Ask a Question

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

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

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top