R
Rui Maciel
Consider the following test program:
<code>
#include <string.h>
#include <stdio.h>
struct buffer
{
#define BUFFER_SIZE 16
char buffer[BUFFER_SIZE];
char *p; /* cursor */
char *q; /* YYMARKER */
char *marker; /* token start marker */
char *limit; /* limit marker */
};
void fill(FILE *file, struct buffer *b)
{
if(feof(file))
{
}
else if(b->p > b->limit - 10)
{
memmove(b->buffer,b->marker, b->limit - b->marker);
b->limit = b->buffer + (b->limit - b->marker) + fread(b->buffer + (b->limit
- b->marker),sizeof(char),BUFFER_SIZE-(b->limit-b->marker),file);
b->p = b->buffer + (b->p - b->marker);
b->marker = b->buffer;
*b->limit = '\0'; // <----- offending line
}
}
int main(void)
{
struct buffer b = {.p = b.buffer+BUFFER_SIZE, .q= b.buffer+BUFFER_SIZE, .marker =
b.buffer+BUFFER_SIZE, .limit = b.buffer+BUFFER_SIZE};
fill(stdin, &b);
return 0;
}
</code>
I've noticed that the pointer dereferencing done at the marked offending line not only sets
*b->limit to '\0' but also has the nasty side effect of screwing up with the address
pointed to by b->p. For example, running the example code on GDB does the following:
<gdb output>
23 b->limit = b->buffer + (b->limit - b->marker) + fread(b->buffer +
(b->limit - b->marker),sizeof(char),BUFFER_SIZE-(b->limit-b->marker),file);
(gdb)
asdf asdf asdf adsf
24 b->p = b->buffer + (b->p - b->marker);
(gdb) n
25 b->marker = b->buffer;
(gdb) n
26 *b->limit = '\0'; // <----- offending line
(gdb) print *b
$1 = {buffer = "asdf asdf asdf a", p = 0x7fffffffdce0 "asdf asdf asdf
a\340\334\377\377\377\177", q = 0x7fffffffdcf0 "\340\334\377\377\377\177",
marker = 0x7fffffffdce0 "asdf asdf asdf a\340\334\377\377\377\177", limit =
0x7fffffffdcf0 "\340\334\377\377\377\177"}
(gdb) n
28 }
(gdb) print *b
$2 = {buffer = "asdf asdf asdf a", p = 0x7fffffffdc00 "\021 d\r", q = 0x7fffffffdcf0 "",
marker = 0x7fffffffdce0 "asdf asdf asdf a", limit = 0x7fffffffdcf0 ""}
</gdb output>
So, is this supposed to happen? I was expecting that the pointer dereference would only
change the value stored in the memory address pointed to by b->limit. Why is that memory
dereferencing screwing up with b->p?
Thanks in advance,
Rui Maciel
<code>
#include <string.h>
#include <stdio.h>
struct buffer
{
#define BUFFER_SIZE 16
char buffer[BUFFER_SIZE];
char *p; /* cursor */
char *q; /* YYMARKER */
char *marker; /* token start marker */
char *limit; /* limit marker */
};
void fill(FILE *file, struct buffer *b)
{
if(feof(file))
{
}
else if(b->p > b->limit - 10)
{
memmove(b->buffer,b->marker, b->limit - b->marker);
b->limit = b->buffer + (b->limit - b->marker) + fread(b->buffer + (b->limit
- b->marker),sizeof(char),BUFFER_SIZE-(b->limit-b->marker),file);
b->p = b->buffer + (b->p - b->marker);
b->marker = b->buffer;
*b->limit = '\0'; // <----- offending line
}
}
int main(void)
{
struct buffer b = {.p = b.buffer+BUFFER_SIZE, .q= b.buffer+BUFFER_SIZE, .marker =
b.buffer+BUFFER_SIZE, .limit = b.buffer+BUFFER_SIZE};
fill(stdin, &b);
return 0;
}
</code>
I've noticed that the pointer dereferencing done at the marked offending line not only sets
*b->limit to '\0' but also has the nasty side effect of screwing up with the address
pointed to by b->p. For example, running the example code on GDB does the following:
<gdb output>
23 b->limit = b->buffer + (b->limit - b->marker) + fread(b->buffer +
(b->limit - b->marker),sizeof(char),BUFFER_SIZE-(b->limit-b->marker),file);
(gdb)
asdf asdf asdf adsf
24 b->p = b->buffer + (b->p - b->marker);
(gdb) n
25 b->marker = b->buffer;
(gdb) n
26 *b->limit = '\0'; // <----- offending line
(gdb) print *b
$1 = {buffer = "asdf asdf asdf a", p = 0x7fffffffdce0 "asdf asdf asdf
a\340\334\377\377\377\177", q = 0x7fffffffdcf0 "\340\334\377\377\377\177",
marker = 0x7fffffffdce0 "asdf asdf asdf a\340\334\377\377\377\177", limit =
0x7fffffffdcf0 "\340\334\377\377\377\177"}
(gdb) n
28 }
(gdb) print *b
$2 = {buffer = "asdf asdf asdf a", p = 0x7fffffffdc00 "\021 d\r", q = 0x7fffffffdcf0 "",
marker = 0x7fffffffdce0 "asdf asdf asdf a", limit = 0x7fffffffdcf0 ""}
</gdb output>
So, is this supposed to happen? I was expecting that the pointer dereference would only
change the value stored in the memory address pointed to by b->limit. Why is that memory
dereferencing screwing up with b->p?
Thanks in advance,
Rui Maciel