Why can I do this?

Discussion in 'C Programming' started by Miguel, Oct 11, 2003.

  1. Miguel

    Miguel Guest

    Why can I do this?? this is a cycle that when it reaches ? puts a
    termination caracter \0, what I want to do is separate one String in
    two

    for(i=strlen(path);i>=0;i--){

    if(!isspace(path)){
    j++;
    printf("nao e um espaço j->%d",j);
    }
    if (path=='?'){
    path=='\0'; --------->>>>>>>>>>>SEGMENTACION FAULT HERE
    buf = (char*) malloc(j*sizeof(char));
    strcpy(buf,&path[i+1]);
    }
    }
     
    Miguel, Oct 11, 2003
    #1
    1. Advertising

  2. (Miguel) wrote:
    >Why can I do this?? this is a cycle that when it reaches ? puts a
    >termination caracter \0, what I want to do is separate one String in
    >two
    >
    > for(i=strlen(path);i>=0;i--){
    >
    > if(!isspace(path)){
    > j++;
    > printf("nao e um espaço j->%d",j);
    > }
    > if (path=='?'){
    > path=='\0'; --------->>>>>>>>>>>SEGMENTACION FAULT HERE


    How is "path" defined???

    Perhaps something like,

    char *path = "/some/data/directory/";

    If so, what you have is a pointer to a string literal, which is
    allowed to be in write protected memory, and attempting to
    modify it will cause a seg fault.

    > buf = (char*) malloc(j*sizeof(char));


    If you have properly included the stdlib.h header there is no
    reason to use a cast. Likewise, sizeof(char) is guaranteed to
    be equal to 1, so it is unnecessary. Your statement should be

    buf = malloc(j);

    --
    Floyd L. Davidson <http://web.newsguy.com/floyd_davidson>
    Ukpeagvik (Barrow, Alaska)
     
    Floyd Davidson, Oct 11, 2003
    #2
    1. Advertising

  3. Miguel

    Mike Wahler Guest

    "Miguel" <> wrote in message
    news:...
    > Why can I do this?? this is a cycle that when it reaches ? puts a
    > termination caracter \0, what I want to do is separate one String in
    > two
    >
    > for(i=strlen(path);i>=0;i--){
    >
    > if(!isspace(path)){
    > j++;
    > printf("nao e um espaço j->%d",j);
    > }


    Here, 'i' is equal to -1.

    > if (path=='?'){


    'path[-1]' is probably outside the bounds of your array.
    Evaluating it gives undefined behavior.
    Dont Do That.


    > path=='\0'; --------->>>>>>>>>>>SEGMENTACION FAULT HERE


    Probably undefined behavior.

    I say "probably" because you don't show how much
    memory is actually represented by 'path'.

    > buf = (char*) malloc(j*sizeof(char));


    Don't cast the return value from 'malloc()'
    sizeof(char) is one by definition.

    buf = malloc(j);

    > strcpy(buf,&path[i+1]);
    > }
    > }


    -Mike
     
    Mike Wahler, Oct 11, 2003
    #3
  4. Miguel

    Don Porges Guest

    "Miguel" <> wrote in message news:...
    > Why can I do this?? this is a cycle that when it reaches ? puts a
    > termination caracter \0, what I want to do is separate one String in
    > two
    >
    > for(i=strlen(path);i>=0;i--){
    >
    > if(!isspace(path)){
    > j++;
    > printf("nao e um espaço j->%d",j);
    > }
    > if (path=='?'){
    > path=='\0'; --------->>>>>>>>>>>SEGMENTACION FAULT HERE
    > buf = (char*) malloc(j*sizeof(char));
    > strcpy(buf,&path[i+1]);
    > }
    > }


    Among other things, you have

    path=='\0'; /* With 2 = characters */

    where I'm sure you mean

    path='\0'; /* With 1 = character */
     
    Don Porges, Oct 12, 2003
    #4
  5. "Mike Wahler" <> wrote:
    >"Miguel" <> wrote in message
    >news:...
    >> Why can I do this?? this is a cycle that when it reaches ? puts a
    >> termination caracter \0, what I want to do is separate one String in
    >> two
    >>
    >> for(i=strlen(path);i>=0;i--){
    >>
    >> if(!isspace(path)){
    >> j++;
    >> printf("nao e um espaço j->%d",j);
    >> }

    >
    >Here, 'i' is equal to -1.


    Can't happen. The value of i is between strlen(path) and 0,
    otherwise the for loop would be exited. Perhaps this is a
    good reason for more whitespace in the code, to make it more
    readable...

    for(i = strlen(path); i >= 0; i--){

    >> if (path=='?'){

    >
    >'path[-1]' is probably outside the bounds of your array.
    >Evaluating it gives undefined behavior.
    >Dont Do That.


    See above.

    >> path=='\0'; --------->>>>>>>>>>>SEGMENTACION FAULT HERE

    >
    >Probably undefined behavior.
    >
    >I say "probably" because you don't show how much
    >memory is actually represented by 'path'.


    The value of i cannot be less than 0 and cannot be greater than
    the length of the string. Therefore we do know how much
    memory is represented by 'path' and we know that path is
    within part of that memory.

    >> buf = (char*) malloc(j*sizeof(char));

    >
    >Don't cast the return value from 'malloc()'
    >sizeof(char) is one by definition.
    >
    >buf = malloc(j);
    >
    >> strcpy(buf,&path[i+1]);


    Personally, I think that is too ugly. It is technically correct,
    but I'd do it this way

    strcpy(buf, path + i + 1);

    >> }
    >> }

    >
    >-Mike
    >
    >


    --
    Floyd L. Davidson <http://web.newsguy.com/floyd_davidson>
    Ukpeagvik (Barrow, Alaska)
     
    Floyd Davidson, Oct 12, 2003
    #5
  6. Miguel

    Mike Wahler Guest

    "Floyd Davidson" <> wrote in message
    news:...
    > "Mike Wahler" <> wrote:
    > >"Miguel" <> wrote in message
    > >news:...
    > >> Why can I do this?? this is a cycle that when it reaches ? puts a
    > >> termination caracter \0, what I want to do is separate one String in
    > >> two
    > >>
    > >> for(i=strlen(path);i>=0;i--){
    > >>
    > >> if(!isspace(path)){
    > >> j++;
    > >> printf("nao e um espaço j->%d",j);
    > >> }

    > >
    > >Here, 'i' is equal to -1.

    >
    > Can't happen.


    *Will* happen. The 'for' loop iterates while 'i'
    is greater than or equal to zero. The only changes
    made to 'i' are in the iteration expression of the
    'for' loop (i--). So the only way for the loop to
    terminate is when 'i' becomes equal to -1.


    > The value of i is between strlen(path) and 0,


    For a while, yes. Then when 'i' becomes zero,
    the 'i--' makes it -1, the loop iterates one more
    time, evalutes 'i >= 0' as false, and exits.
    Thus i == -1 immediately after the loop.

    > otherwise the for loop would be exited.


    It *is* exited.

    >Perhaps this is a
    > good reason for more whitespace in the code, to make it more
    > readable...


    Nothing to do with whitespace.

    >
    > for(i = strlen(path); i >= 0; i--){
    >
    > >> if (path=='?'){

    > >
    > >'path[-1]' is probably outside the bounds of your array.
    > >Evaluating it gives undefined behavior.
    > >Dont Do That.

    >
    > See above.


    Read the code again.

    >
    > >> path=='\0'; --------->>>>>>>>>>>SEGMENTACION FAULT HERE

    > >
    > >Probably undefined behavior.
    > >
    > >I say "probably" because you don't show how much
    > >memory is actually represented by 'path'.

    >
    > The value of i cannot be less than 0 and cannot be greater than
    > the length of the string.


    The code specifically gives 'i' a value of -1.
    Look again.

    >Therefore we do know how much
    > memory is represented by 'path'


    There is absolutely no way to determine the size of
    the memory to which 'path' points from the code provided.

    >and we know that path is
    > within part of that memory.


    No we don't, not with the information provided.

    Here's what we can see:

    void foo(char *path)
    {
    for(i=strlen(path);i>=0;i--)
    {
    }
    }

    Here's a function from another part of a program
    we don't see:

    void f1()
    {
    char array[10] = "hello";
    foo(array);
    }

    So now, only looking at 'foo', tell me how large block of
    memory the pointer 'path' is pointing into.

    Another possible function which calls 'foo()'
    which we don't see:

    void f2()
    {
    char array[10] = "hello world";
    foo(array + 5);
    }

    Now, only looking at 'foo', tell me how large block of
    memory the pointer 'path' is pointing into.

    In the case of this call to 'foo()' the expression
    'path[-1]' is OK.

    But my point is, without seeing full context, we
    *cannot* know the size of what 'path' points to.

    That's why I said "probably" (guessing that the
    beginning address of an array was passed, since
    that's the most common thing to do). We don't
    *know*.

    -Mike
     
    Mike Wahler, Oct 12, 2003
    #6
  7. "Mike Wahler" <> wrote:
    >"Floyd Davidson" <> wrote:
    >> "Mike Wahler" <> wrote:
    >> >"Miguel" <> wrote:
    >> >>
    >> >> for(i=strlen(path);i>=0;i--){
    >> >>
    >> >> if(!isspace(path)){
    >> >> j++;
    >> >> printf("nao e um espaço j->%d",j);
    >> >> }
    >> >
    >> >Here, 'i' is equal to -1.

    >>
    >> Can't happen.

    >
    >*Will* happen. The 'for' loop iterates while 'i'
    >is greater than or equal to zero. The only changes
    >made to 'i' are in the iteration expression of the
    >'for' loop (i--). So the only way for the loop to
    >terminate is when 'i' becomes equal to -1.


    Exactly. The loop will terminate when i becomes -1.

    Nothing inside the loop will ever be executed when
    the value of i is -1.

    >> The value of i is between strlen(path) and 0,

    >
    >For a while, yes. Then when 'i' becomes zero,
    >the 'i--' makes it -1, the loop iterates one more
    >time, evalutes 'i >= 0' as false, and exits.


    See C99 6.8.5.3. The loop will *not* iterate one
    more time. the "i--" is evaluated at the *end* of
    each loop, not at the beginning of the loop. The
    loop will *never* be executed with i set to -1.

    >Thus i == -1 immediately after the loop.
    >
    >> otherwise the for loop would be exited.

    >
    >It *is* exited.


    But the assignments to path were done *within* the
    loop, not after it was exited.

    Here is the entire snippet of code from the original post:

    for(i=strlen(path);i>=0;i--){

    if(!isspace(path)){
    j++;
    printf("nao e um espaço j->%d",j);
    }
    if (path=='?'){
    path=='\0'; --------->>>>>>>>>>>SEGMENTACION FAULT HERE
    buf = (char*) malloc(j*sizeof(char));
    strcpy(buf,&path[i+1]);
    }
    }

    At exit, n will be equal to -1, but at no point within the
    execution loop will it ever be less than 0.

    >>Perhaps this is a
    >> good reason for more whitespace in the code, to make it more
    >> readable...

    >
    >Nothing to do with whitespace.


    Well, your description of how a for loop works above is
    incorrect, and/or it also seems you missed the beginning brace
    of the compound statement making up the for loop too. The
    assignment to path[n] is taking place within the loop, not after
    the loop is terminated.

    >> for(i = strlen(path); i >= 0; i--){
    >>
    >> >> if (path=='?'){
    >> >
    >> >'path[-1]' is probably outside the bounds of your array.
    >> >Evaluating it gives undefined behavior.
    >> >Dont Do That.

    >>
    >> See above.

    >
    >Read the code again.


    Indeed.

    >>
    >> >> path=='\0'; --------->>>>>>>>>>>SEGMENTACION FAULT HERE
    >> >
    >> >Probably undefined behavior.
    >> >
    >> >I say "probably" because you don't show how much
    >> >memory is actually represented by 'path'.

    >>
    >> The value of i cannot be less than 0 and cannot be greater than
    >> the length of the string.

    >
    >The code specifically gives 'i' a value of -1.
    >Look again.


    But not where that line of code is.

    >>Therefore we do know how much
    >> memory is represented by 'path'

    >
    >There is absolutely no way to determine the size of
    >the memory to which 'path' points from the code provided.


    We know how much there is which contains a valid string. There
    could be more, but we don't care because we aren't writing outside
    the boundaries of the string, only within it.

    I think the OP's problem is simply that path actually is a
    pointer, not an array, and points to a string literal in read
    only memory.

    >>and we know that path is
    >> within part of that memory.

    >
    >No we don't, not with the information provided.
    >
    >Here's what we can see:
    >
    >void foo(char *path)
    >{
    > for(i=strlen(path);i>=0;i--)
    > {
    > }
    >}


    Exactly. Now take that code and add a main() function and a
    couple of function calls to meter it, and you'll see that

    1) inside the for loop the value of i is never
    less than 0, and

    2) i always indexes a valid subscript within path
    (assuming that path points to a valid string).

    Here, try it:

    #include <stdio.h>
    #include <string.h>
    void foo(char *path) {
    int i;
    for(i = strlen(path); i >= 0; --i) {
    printf("At i == %d; path is [%s]\n", i, &path);
    }
    }
    int main(int argc, char *argv[]) {
    if (argc > 1) foo(argv[1]);
    return 0;
    }

    Here is what it prints out:

    >./foo bar

    At i == 3; path is []
    At i == 2; path is [r]
    At i == 1; path is [ar]
    At i == 0; path is [bar]

    You cannot find a valid string for which i will ever be -1.

    >Here's a function from another part of a program
    >we don't see:
    >
    >void f1()
    >{
    > char array[10] = "hello";
    > foo(array);
    >}
    >
    >So now, only looking at 'foo', tell me how large block of
    >memory the pointer 'path' is pointing into.
    >
    >Another possible function which calls 'foo()'
    >which we don't see:
    >
    >void f2()
    >{
    > char array[10] = "hello world";
    > foo(array + 5);
    >}
    >
    >Now, only looking at 'foo', tell me how large block of
    >memory the pointer 'path' is pointing into.
    >
    >In the case of this call to 'foo()' the expression
    >'path[-1]' is OK.
    >
    >But my point is, without seeing full context, we
    >*cannot* know the size of what 'path' points to.


    We only need to know how big the string contained in
    the array is. All of the above is both wonderful and
    useless to the OP's program.

    >That's why I said "probably" (guessing that the
    >beginning address of an array was passed, since
    >that's the most common thing to do). We don't
    >*know*.
    >
    >-Mike



    --
    Floyd L. Davidson <http://web.newsguy.com/floyd_davidson>
    Ukpeagvik (Barrow, Alaska)
     
    Floyd Davidson, Oct 12, 2003
    #7
  8. (Miguel) wrote:

    >Why can I do this?? this is a cycle that when it reaches ? puts a
    >termination caracter \0, what I want to do is separate one String in
    >two
    >


    First off:
    - How is path declared?
    - You failed to initialize j (at least in the code you posted).

    > for(i=strlen(path);i>=0;i--){
    >
    > if(!isspace(path)){
    > j++;


    Next, you increment j only if path is not a white-space (see below
    for the consequences).

    > printf("nao e um espaço j->%d",j);
    > }
    > if (path=='?'){
    > path=='\0'; --------->>>>>>>>>>>SEGMENTACION FAULT HERE


    No SEGFAULT here, but warning: statement with no effect.
    You most probably want:

    path = '\0';

    instead.

    > buf = (char*) malloc(j*sizeof(char));


    Even if you change this (strongly suggested) to:

    buf = malloc( j );

    your code most probably SEGFAULTs in strcpy, because if white-spaces
    occurred (see above), you fail to allocate enough space for buf to
    hold the string you copy!

    > strcpy(buf,&path[i+1]);
    > }
    > }


    And, of course, you have to make sure that path is not a pointer to a
    string literal (which [the literal] you aren't allowed to change).

    I deliberately changed your code and completed it to form a compilable
    example; here it is:

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

    #define PATHLEN 42

    int main( void )
    {
    int i;
    int j;
    char *buf = NULL;
    char path[PATHLEN] = "abcd efg/xyz ? qwert/h jk";

    printf( "Before: %s\n", path );

    j = 0;
    for( i = strlen(path); i >= 0; i-- )
    {
    j++;
    if ( path == '?' )
    {
    path = '\0';
    buf = malloc( j );
    strcpy( buf, path + i + 1 );
    }
    }

    printf( "After: %s\n %s\n", path, buf );

    free( buf );
    return 0;
    }

    However, note that this code still produces a memory leak if path
    contains more than one '?'!!!

    Regards
    --
    Irrwahn
    ()
     
    Irrwahn Grausewitz, Oct 12, 2003
    #8
  9. "Mike Wahler" <> wrote:
    >
    >"Miguel" <> wrote in message
    >news:...
    >> Why can I do this?? this is a cycle that when it reaches ? puts a
    >> termination caracter \0, what I want to do is separate one String in
    >> two
    >>
    >> for(i=strlen(path);i>=0;i--){
    >>
    >> if(!isspace(path)){
    >> j++;
    >> printf("nao e um espaço j->%d",j);
    >> }

    >
    >Here, 'i' is equal to -1.


    Apparently, no. But admittedly I misread the code the first time I came
    across, most probably the same way you did, it seems to me; so all your
    statements about UB below are right claims based on a wrong premiss.
    Things happen. :)

    [OT]
    This is just another good example for why I dislike the "Indian (H)ill"
    bracing style. No offense or style war intended, just my personal
    opinion.
    [/OT]

    >
    >> if (path=='?'){

    >
    >'path[-1]' is probably outside the bounds of your array.
    >Evaluating it gives undefined behavior.
    >Dont Do That.


    See above.

    >
    >> path=='\0'; --------->>>>>>>>>>>SEGMENTACION FAULT HERE

    >
    >Probably undefined behavior.


    See above.

    >I say "probably" because you don't show how much
    >memory is actually represented by 'path'.
    >
    >> buf = (char*) malloc(j*sizeof(char));

    >
    >Don't cast the return value from 'malloc()'
    >sizeof(char) is one by definition.
    >
    >buf = malloc(j);


    Right, that's much better.

    >
    >> strcpy(buf,&path[i+1]);
    >> }
    >> }

    >


    Regards
    --
    Irrwahn
    ()
     
    Irrwahn Grausewitz, Oct 12, 2003
    #9
  10. "Mike Wahler" <> wrote:

    >
    >"Floyd Davidson" <> wrote in message
    >news:...
    >> "Mike Wahler" <> wrote:
    >> >"Miguel" <> wrote in message
    >> >news:...

    <SNIP>
    >> >> for(i=strlen(path);i>=0;i--){
    >> >>
    >> >> if(!isspace(path)){
    >> >> j++;
    >> >> printf("nao e um espaço j->%d",j);
    >> >> }
    >> >
    >> >Here, 'i' is equal to -1.

    >>
    >> Can't happen.

    >
    >*Will* happen.


    *Cannot* happen; you misread (I did too in the first place),
    see my other replies.

    <SNIP>

    Regards
    --
    Irrwahn
    ()
     
    Irrwahn Grausewitz, Oct 12, 2003
    #10
  11. Miguel

    Mike Wahler Guest

    Re: [why can't I see?] was: Why can I do this?

    "Irrwahn Grausewitz" <> wrote in message
    news:...

    > >> Can't happen.

    > >
    > >*Will* happen.

    >
    > *Cannot* happen; you misread (I did too in the first place),
    > see my other replies.


    My wife told me it was not a good idea to stay
    awake for three days. :)

    I commited a similar faux pas with a 'dynterpret_cast'
    in clc++ :)

    Apologies for my idiotic post, Floyd.

    G'night all!

    -Mike
     
    Mike Wahler, Oct 12, 2003
    #11
  12. Re: [why can't I see?] was: Why can I do this?

    "Mike Wahler" <> wrote:

    >My wife told me it was not a good idea to stay
    >awake for three days. :)


    See my sig. :)

    Irrwahn
    --
    The best cure for insomnia is to get a lot of sleep.
     
    Irrwahn Grausewitz, Oct 12, 2003
    #12
  13. Re: [why can't I see?] was: Why can I do this?

    "Mike Wahler" <> wrote:
    >"Irrwahn Grausewitz" <> wrote in message
    >news:...
    >
    >> >> Can't happen.
    >> >
    >> >*Will* happen.

    >>
    >> *Cannot* happen; you misread (I did too in the first place),
    >> see my other replies.

    >
    >My wife told me it was not a good idea to stay
    >awake for three days. :)
    >
    >I commited a similar faux pas with a 'dynterpret_cast'
    >in clc++ :)
    >
    >Apologies for my idiotic post, Floyd.
    >
    >G'night all!
    >
    >-Mike


    Everybody does that. The measure of a person is whether they get
    overly snotty in the process (you didn't) and then how they react
    when they realize they goofed.

    You measure up pretty well.

    --
    Floyd L. Davidson <http://web.newsguy.com/floyd_davidson>
    Ukpeagvik (Barrow, Alaska)
     
    Floyd Davidson, Oct 12, 2003
    #13
  14. Miguel

    Mike Wahler Guest

    Re: [why can't I see?] was: Why can I do this?

    "Irrwahn Grausewitz" <> wrote in message
    news:...
    > "Mike Wahler" <> wrote:
    >
    > >My wife told me it was not a good idea to stay
    > >awake for three days. :)

    >
    > See my sig. :)
    >
    > Irrwahn
    > --
    > The best cure for insomnia is to get a lot of sleep.


    Not insomnia, but a poor "time : necessary tasks" ratio. :)

    -Mike
     
    Mike Wahler, Oct 12, 2003
    #14
  15. Groovy hepcat Miguel was jivin' on 11 Oct 2003 14:07:12 -0700 in
    comp.lang.c.
    Why can I do this?'s a cool scene! Dig it!

    >Why can I do this?? this is a cycle that when it reaches ? puts a
    >termination caracter \0, what I want to do is separate one String in
    >two
    >
    > for(i=strlen(path);i>=0;i--){
    >
    > if(!isspace(path)){
    > j++;
    > printf("nao e um espaço j->%d",j);
    > }
    > if (path=='?'){
    > path=='\0'; --------->>>>>>>>>>>SEGMENTACION FAULT HERE

    ^^
    You're comparing here, instead of assigning. If this isn't your real
    code, then why isn't it? Cut and paste; do not retype.

    > buf = (char*) malloc(j*sizeof(char));


    You are leaking memory if this line is executed more than once.
    Nowhere do you free this memory, but just overwrite the previous value
    of buf, which may be the address of the last block of dynamically
    allocated memory.

    > strcpy(buf,&path[i+1]);
    > }
    > }


    Since you posted only a small portion of code, instead of a whole
    program, we cannot compile it to see what might be wrong. We're left
    to guess what might be the cause of the problem.
    Post a *complete* program that demonstrates the problem. By
    "complete" I don't mean a 50000 line program that does everything. I
    mean a small program that just tries to do one thing, but one that is
    complete enough to compile. Cut down your full program to the smallest
    complete program that still demonstrates the problem. (And do try to
    compile and run it to make sure it *does* actually demonstrate the
    problem.) Cut and paste this code into your post; do not retype it.

    --

    Dig the even newer still, yet more improved, sig!

    http://alphalink.com.au/~phaywood/
    "Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
    I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
     
    Peter Shaggy Haywood, Oct 15, 2003
    #15
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?VGltOjouLg==?=

    Why, why, why???

    =?Utf-8?B?VGltOjouLg==?=, Jan 27, 2005, in forum: ASP .Net
    Replies:
    6
    Views:
    572
    Juan T. Llibre
    Jan 27, 2005
  2. Horace Nunley

    why why why does function not work

    Horace Nunley, Sep 27, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    461
    =?Utf-8?B?UGV0ZXIgQnJvbWJlcmcgW0MjIE1WUF0=?=
    Sep 27, 2006
  3. Mr. SweatyFinger

    VWD why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    384
    =?Utf-8?B?Q2lhcmFuIE8nJycnRG9ubmVsbA==?=
    Dec 21, 2006
  4. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    904
    Mark Rae
    Dec 21, 2006
  5. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,969
    Smokey Grindel
    Dec 2, 2006
Loading...

Share This Page