Why this code works fine under C6.0, but failed under .NET compiler?

Discussion in 'Windows Vista Drivers' started by Bienvenue, Sep 28, 2006.

  1. Bienvenue

    Bienvenue Guest

    This code works fine under C/C++ 6.0, why it fails with .NET compiler?

    With .NET Compiler I got "Unhandled Acception" at this line below:

    *(ckflag+i) = *string; // store this character for duplicate check

    *ckflag points to a valid allocated string. Why would I need to handle the
    acception any way since my temp buffer is not overrun?

    Can some one please look over my code?

    Thanks



    ------------------------------------------------------------------------------------------------------------

    char ReturnNondup(char *string) // Returns the first non-duplicated charact
    // of string= "abccabdef"
    // d should be returned, it used to work with C 6.0

    { // each character we looked at will be an offset to our table map
    int i;
    #define TO_IGNORE '*' // This is used to mark a duplicated character
    char *ckflag = new char[] = "...........................";
    // temp buf of string 27 characters equivalent to ASCII table
    // Going though a single pass of 1 million characters

    while (string) { // While string is not NULL

    i =((int)*string)-97; // 97 = character 'a', this is the offset to our index
    table.

    if (*(ckflag+i)!= '.') // we have something to look up?
    {
    // If 'a' (or whatever) has been seen before then this is a dup
    if (*(ckflag+i)== *string)
    *(ckflag+i)= TO_IGNORE; // mark it with a flag to ignore it
    }
    else
    *(ckflag+i) = *string; // store this character for duplicate check

    string++;
    }


    // going through our index table, any blank in the index is telling us that
    character position has no duplication

    char *flagorg = ckflag; // Remember the starting of index

    while (*ckflag != TO_IGNORE) { // while looking at duplicated number keep
    going through our index table

    ckflag++;

    }

    return (char)(ckflag-flagorg) +97; // convert the index into ASCII, this is
    the first character non-duplicated

    }
     
    Bienvenue, Sep 28, 2006
    #1
    1. Advertisements

  2. Bienvenue

    Pavel A. Guest

    Wrong newsgroup.
    --PA

    [snip]
     
    Pavel A., Sep 28, 2006
    #2
    1. Advertisements

  3. What does this have to do with device drivers?
    Same as ckflag = *string;
    It is 'allocated' by this line:
    [code snipped]

    This is equivalent to this:
    char *ckflag = "...........................";
    new char[];

    The problems are:
    - The string ckflag points to cannot be changed.
    - The pointer new char[] returns is never deleted.

    And I don't know how much "new char[]" allocates.

    Change it to:

    char buffer[] = "...........................";
    char *ckflag = buffer;

    (There are several other problem with the code.)
     
    Thomas J. Gritzan, Sep 28, 2006
    #3
  4. Bienvenue

    Bienvenue Guest

    You're right, However I thought Device Driver Group is smarter since
    they use C6, and C7. This problem is being issued by C7, if you don't know,
    no problem.

    Thanks any way.


     
    Bienvenue, Sep 29, 2006
    #4
  5. 1. You cannot initialize char* with a string literal. It may point to
    read-only memory, then any attempt to modify it will cause an exeption.
    2. Are you aware that you can simply write ckflag instead of ugly
    *(ckflag+i) ? If not, you need to get some more C training or read some
    books.
    3. I cannot complrehend this line: char *ckflag = new char[] =
    "...........................";
    What you mean there? It should not compile as is.
     
    Alexander Grigoriev, Sep 29, 2006
    #5
  6. Bienvenue

    Bienvenue Guest

    Thanks Alexander for taking at look at this problem. You said:
    *ckflag points to an allocted buffer in heap-memory, SEE new char[27] =
    how can this be read-only memory?

    I changed it to make it look easier to read, the problem still occurred at
    the same spot:

    char *ckflag;
    ckflag = new char[27] = " "; // index table


    Yes, the asm is the same. I already tried it before posting this question.


    I have found my error. somehow I have accidentally remove the *
    in front of *string. This cause the while loop to go beyond the string
    limit which cause access violation.
    So problem is solved.

    while (*string) { // While string is not NULL
    Thanks Alex.
     
    Bienvenue, Sep 29, 2006
    #6
  7. This line still doesn't make sense:

    ckflag = new char[27] = " "; // index table

    If you think it will initialize your newly allocated buffer, it won't
    happen.

     
    Alexander Grigoriev, Sep 29, 2006
    #7
  8. Bienvenue

    Ray Trent Guest

    I was quite confused by this too, so I tried it, and indeed it seems to
    compile and superficially work, except of course that as expected the
    buffer is actually a read-only string and accvio's if you try to modify it.

    It appears that what it's doing is assigning the pointer to the constant
    string into the temporary variable of type char* that new returns, and
    then of course assigning the result of that "=" operator into the
    declared char* variable. So it's functionally equivalent to:
    char* ckflag = " ";
    with the side effect of allocating some memory and throwing away the
    pointer.

    In spite of technically perhaps being legal code, I'm still really
    surprised that it compiles in both VC 6.0 and VS 2005 without complaint,
    even with warning level 4 (though VS2005 at least complains about the
    unreferenced parameters of main :).

    I bet you Prefast finds it, though :)

    e.g.

    int main(int argc, char* argv[])
    {
    char* szFlag = new char[27] = "abcdefghijklmnopqrstuvwxyz ";
    printf("|%s|\n", szFlag);
    szFlag[0] = 'n';
    printf("|%s|\n", szFlag);
    Sleep(10000);
    return 0;
    }

    This blows up at the line "szFlag[0] = 'n';" as you would expect. But
    the printf does print out "abcdefghijklmnopqrstuvwxyz |" (note the
    interesting fact that the string is longer than the allocated buffer).

    Anyway, you do leak the allocated memory and it doesn't do what the OP
    wants it to do, but it is still kind of interesting...

     
    Ray Trent, Sep 29, 2006
    #8
  9. It appears that what it's doing is assigning the pointer to the constant
    I don't think that operator "new" produces a lvalue, which is required left
    side of "=".
     
    Maxim S. Shatskih, Oct 2, 2006
    #9
  10. Bienvenue

    Ray Trent Guest

    Yeah, I wouldn't have thought so either, but the code I posted does
    compile (in both VC6 and VS2005) and it "runs". The "hidden temporary
    variable" idea is about the only explanation I can come up with.
     
    Ray Trent, Oct 2, 2006
    #10
  11. I think that this:
    char* szFlag = new char[27] = "abcdefghijklmnopqrstuvwxyz ";

    ....doesn't have right to left associativity as this would have:
    szFlag = new char[27] = "abcdefghijklmnopqrstuvwxyz ";

    Since the first "=" sign isn't the assignment operator but part of the
    variable definition syntax. So it is like this:

    (char* szFlag = new char[27]) = "abcdefghijklmnopqrstuvwxyz ";

    The pointer returned by new is assign to szFlag, then overwritten with the
    string literal pointer.

    To be sure about this, we should ask in comp.lang.c++.
     
    Thomas J. Gritzan, Oct 2, 2006
    #11
  12. Bienvenue

    Ray Trent Guest

    Probably this is getting a bit ridiculous for this group, but the left
    hand "=" is, in fact, the assignment operator. If you declare an
    overridden operator"=" it will get called during variable initialization.

    But in any event, on the off chance that I'm remembering that wrong,

    char *szFlag;
    szFlag = new char[27] = "abcdefghijklmnopqrstuvwxyz ";

    Also works and has the same results.
     
    Ray Trent, Oct 2, 2006
    #12
  13. You are right. From the disassembly, it seems to be a temporary.
    Even
    new char = "test";
    compiles with VC7.1, but gcc and the comeau compiler give an error.

    F'up to poster.
     
    Thomas J. Gritzan, Oct 2, 2006
    #13
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.