Charcter Pointer Problem

B

bent lee

Hi

I need help with something thats bugging me for a while.
The only way I can get the program to print something
is if I do this in the while loop.

i = 0;
while ((c = getc(fp)) != EOF) {
bp[i++] = c
}
bp = '\0'

instead of

while ((c = getc(fp)) != EOF) {
*bp++ = c;
}
*bp = '\0';

why can't I get it to work?

here is the full program.
i'm running gentoo/linux.

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

size_t bufsize = 512;

int main(int argc, char *argv[])
{
FILE *fp;
char *bp;
int i;
int c;

*argv++;
fp = fopen(*argv, "r");

if ((bp = malloc(bufsize * sizeof(char *))) == NULL) {
printf("cannot alocate memory.\n");
return 1;
}

/*i = 0;*/
while ((c = getc(fp)) != EOF) {
*bp++ = c;
/* bp[i++] = c */
}
*bp = '\0';
/* bp = '\0' */
fclose(fp);

printf("%s", bp);

free(bp);

return 0;
}
 
M

Michael Mair

bent said:
Hi

I need help with something thats bugging me for a while.
The only way I can get the program to print something
is if I do this in the while loop.

i = 0;
while ((c = getc(fp)) != EOF) {
bp[i++] = c
}
bp = '\0'


Your base pointer bp is not modified.
instead of

while ((c = getc(fp)) != EOF) {
*bp++ = c;
}
*bp = '\0';

why can't I get it to work?

Your base pointer is modified.
here is the full program.
i'm running gentoo/linux.

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

size_t bufsize = 512;

int main(int argc, char *argv[])
{
FILE *fp;
char *bp;

You lack a temporary pointer:
char *temp;
int i;
int c;

*argv++;
fp = fopen(*argv, "r");

if ((bp = malloc(bufsize * sizeof(char *))) == NULL) {
printf("cannot alocate memory.\n");
return 1;

Not portable.
exit(EXIT_FAILURE);
is.

Now, let's get a pointer that we may modify:
temp = bp;
/*i = 0;*/
while ((c = getc(fp)) != EOF) {
*bp++ = c;

You change your base pointer. It does not longer point to
the start address of the allocated storage.

This achieves the same with respect to changing the contents
of the allocated storage but does not "forget" the start of
the storage (which is stored in bp):

*temp++ = c;
/* bp[i++] = c */
}
*bp = '\0';

You set *bp = '\0', i.e. bp represents the empty string.

*temp = '\0';
While temp gives you the empty string, bp gives you the
full string.
/* bp = '\0' */
fclose(fp);

printf("%s", bp);


Your version: You print the empty string.
temp version: You print the desired string.
free(bp);

Your version: You free the wrong address -- this leads to undefined
behaviour.
Temp version: everything works as intended.
return 0;
}


Cheers
Michael
 
B

bent lee

Michael said:
bent said:
Hi

I need help with something thats bugging me for a while.
The only way I can get the program to print something
is if I do this in the while loop.

i = 0;
while ((c = getc(fp)) != EOF) {
bp[i++] = c
}
bp = '\0'


Your base pointer bp is not modified.
instead of

while ((c = getc(fp)) != EOF) {
*bp++ = c;
}
*bp = '\0';

why can't I get it to work?

Your base pointer is modified.
here is the full program.
i'm running gentoo/linux.

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

size_t bufsize = 512;

int main(int argc, char *argv[])
{
FILE *fp;
char *bp;

You lack a temporary pointer:
char *temp;
int i;
int c;

*argv++;
fp = fopen(*argv, "r");

if ((bp = malloc(bufsize * sizeof(char *))) == NULL) {
printf("cannot alocate memory.\n");
return 1;

Not portable.
exit(EXIT_FAILURE);
is.

Now, let's get a pointer that we may modify:
temp = bp;
/*i = 0;*/
while ((c = getc(fp)) != EOF) {
*bp++ = c;

You change your base pointer. It does not longer point to
the start address of the allocated storage.

This achieves the same with respect to changing the contents
of the allocated storage but does not "forget" the start of
the storage (which is stored in bp):

*temp++ = c;
/* bp[i++] = c */
}
*bp = '\0';

You set *bp = '\0', i.e. bp represents the empty string.

*temp = '\0';
While temp gives you the empty string, bp gives you the
full string.
/* bp = '\0' */
fclose(fp);

printf("%s", bp);


Your version: You print the empty string.
temp version: You print the desired string.
free(bp);

Your version: You free the wrong address -- this leads to undefined
behaviour.
Temp version: everything works as intended.
return 0;
}


Cheers
Michael


Thanks
 
S

Spiros Bousbouras

bent said:
Hi

I need help with something thats bugging me for a while.
The only way I can get the program to print something
is if I do this in the while loop.

i = 0;
while ((c = getc(fp)) != EOF) {
bp[i++] = c
}
bp = '\0'

instead of

while ((c = getc(fp)) != EOF) {
*bp++ = c;
}
*bp = '\0';

why can't I get it to work?

here is the full program.
i'm running gentoo/linux.

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

size_t bufsize = 512;

int main(int argc, char *argv[])
{
FILE *fp;
char *bp;
int i;
int c;

*argv++;


This dereferences argv and then increases argv by 1.
The dereferenced value gets discarded. So you could
have simply written argv++ But I think that you're not
allowed to modify the value of argv. So instead of doing
that you should have written further down
fp = fopen(*(argv+1), "r"); But you obviously need to also
check that argc > 1
fp = fopen(*argv, "r");

You need to check the return value here for NULL.
if ((bp = malloc(bufsize * sizeof(char *))) == NULL) {

I suspect you mean sizeof(char) here (which is 1) rather
than sizeof(char *)
printf("cannot alocate memory.\n");
return 1;

A return value of 1 works for Unix/Linux but is not portable.
We prefer portable code around here.
}

/*i = 0;*/
while ((c = getc(fp)) != EOF) {
*bp++ = c;
/* bp[i++] = c */
}

Inside the loop you need to check that you don't get
a buffer overflow.
*bp = '\0';
/* bp = '\0' */
fclose(fp);

printf("%s", bp);


At this point bp points to a memory location which
contains the NUL character , not to the beginning of
your buffer.
 
S

Spiros Bousbouras

bent said:
I get a segfault when I do that.

Then I suspect that the file you're reading from
is too large for your buffer. I suggest that you
include in your code all the checks I mentioned
in my previous post and try again. This is the only
way to find out what's wrong. But conceptually
the malloc requires sizeof(char) (or equivalently
sizeof(*bp)).
 
B

bent lee

Spiros said:
Then I suspect that the file you're reading from
is too large for your buffer. I suggest that you
include in your code all the checks I mentioned
in my previous post and try again. This is the only
way to find out what's wrong. But conceptually
the malloc requires sizeof(char) (or equivalently
sizeof(*bp)).

sizeof(*bp) works fine. what is the diff between that and sizeof(char)?
how do I check for buffer overflow?
 
S

Spiros Bousbouras

bent said:
sizeof(*bp) works fine. what is the diff between that and sizeof(char)?

The difference most likely is that on your system
sizeof(char *) > sizeof(char)
so when you are using sizeof(char *) your buffer
becomes large enough to accommodate the input.
But with a larger input you would still get segfault.
That is if the problem is indeed caused by a buffer
overflow. We can't know for sure unless you include
all the relevant checks in your code.
how do I check for buffer overflow?

In the version of your code where you use i you include
the line
if (i >= 512) { <exit with error> }
inside the loop.

In the version of your code where you use bp and assuming
that you have stored the beginning of your buffer inside temp,
then you write
if (bp-temp >= 512) ...
 
K

Keith Thompson

bent lee said:
sizeof(*bp) works fine. what is the diff between that and sizeof(char)?
how do I check for buffer overflow?

I took a quick glance upthread at the original code.

The original code has:

size_t bufsize = 512;
....
char *bp;
....
if ((bp = malloc(bufsize * sizeof(char *))) == NULL) {
printf("cannot alocate memory.\n");
....
}

sizeof(char*) is the size of a pointer to char. You're allocating
enough space to hold 512 pointers, but you're actually storing
characters in the allocated space.

In practice, this just means you're (probably) allocating more space
than you need. But it's a symptom of a failure to keep track of
types, which can easily shoot you in the foot.

Assuming you want to allocate space for 512 characters, you can do this:

bp = malloc(bufsize * sizeof(char));

but this is equivalent and better (since you don't have to repeat the
element type):

bp = malloc(bufsize * sizeof *bp);

or you can take advantage of the fact that you're allocating characters:

bp = malloc(bufsize);
 
B

bent lee

Spiros said:
The difference most likely is that on your system
sizeof(char *) > sizeof(char)
so when you are using sizeof(char *) your buffer
becomes large enough to accommodate the input.
But with a larger input you would still get segfault.
That is if the problem is indeed caused by a buffer
overflow. We can't know for sure unless you include
all the relevant checks in your code.


In the version of your code where you use i you include
the line
if (i >= 512) { <exit with error> }
inside the loop.

In the version of your code where you use bp and assuming
that you have stored the beginning of your buffer inside temp,
then you write
if (bp-temp >= 512) ...

Thanks. sizeof(char) works now. but how do I
read more into the buffer? I know I can make the
size of bufsize bigger. Can I get the temp buffer
to point to the next bp element?
 
C

CBFalconer

bent said:
.... snip ...

Thanks. sizeof(char) works now. but how do I
read more into the buffer? I know I can make the
size of bufsize bigger. Can I get the temp buffer
to point to the next bp element?

Download and read the source for ggets. Available at:

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

--
Some informative links:
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html
 
S

Spiros Bousbouras

bent said:
Thanks. sizeof(char) works now. but how do I
read more into the buffer? I know I can make the
size of bufsize bigger.

Do you mean you know about making the bufsize
bigger using realloc() ? If you know about that then
it's the only method.
Can I get the temp buffer
to point to the next bp element?

I'm not sure what you mean.
 
B

bent lee

Spiros said:
Do you mean you know about making the bufsize
bigger using realloc() ? If you know about that then
it's the only method.


I'm not sure what you mean.

thanks realloc worked like a charm.
don't worry about the other thing
I was talking out of my ass.

I'll post the code for it when I've worked out
the kinks. so you guys can see if i'm doing
the right thing.
 

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

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top