Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. I want to know where i made mistake because memcpy not copy "ab" of char array into my CardCategory variable ?
Forum Updated to NodeBB v4.3 + New Features

I want to know where i made mistake because memcpy not copy "ab" of char array into my CardCategory variable ?

Scheduled Pinned Locked Moved Solved C++ Gurus
17 Posts 5 Posters 2.6k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Q Qt embedded developer

    below i am expecting output of CardCategory as "ab" but not coming why its not coming ?

    i want to know what concepts will help me to identify the mistakes ?

    #include <stdio.h>
    #include <string.h>
    #define byte    unsigned char 
    
    void print (byte *a[])
    {
    
    a="abcdefghijklmnopqrstuvwxyz";
    printf("parsed pointer %s",a);
    
        
    }
    
    
    int main()
    {
        byte str [27],CardCategory[5];
    
        print(&str);
       
       memcpy(&CardCategory[0],&str[0],2); // here i am expecting that str[0] and str[1] get 
     //copied into card category  str  
     printf("\n %s",CardCategory);
    
        return 0;
    }
    

    Actually I have one library function where i passed below variable :
    BYTE GetDatafromDataFile[128];

    like below :

    result = CTOS_DesfireReadData(FileNo, ulOffSet, 0, &GetDatafromDataFile, &DataLen);

    now to store and print response i have used variable

    BYTE CardNumber[10] ;

    like below

    memcpy(&CardNumber[0],GetDatafromDataFile,8);

    whenever i print i got the proper response from card like
    21100095 when i use

    printf("FetchCardDetailsForBalanceInq::CardNumber = %s\n",CardNumber);

    to understand this i have written the above code. SO let me know what changes in above code can help to understand back end things done in CTOS_DesfireReadData();

    M Offline
    M Offline
    mpergand
    wrote on last edited by
    #6

    @Qt-embedded-developer said in I want to know where i made mistake because memcpy not copy "ab" of char array into my CardCategory variable ?:

    void print (byte *a[])

    You declare an array of pointers !

    Rule of thumb: [] has priority over *
    So you have to do:

    char str [27]="hello";
    
    char (*p)[27] = &str;    // declare a pointer to an array of 27 chars
    std::printf("%s\n",*p);
    
    1 Reply Last reply
    0
    • jsulmJ jsulm

      @Qt-embedded-developer In print() you are assigning a pointer to local data! Assignment to a pointer does not copy the data. And your code does not even compile because *[] is not same as char[27]...
      Fix your code and initialise str inside main directly and try memcpy again.

      Q Offline
      Q Offline
      Qt embedded developer
      wrote on last edited by Qt embedded developer
      #7

      @jsulm @Chris-Kawa @mpergand but i have to understand code where i pass address of unsigned char array in function. that function catch this address. store the data like "abcdef" into that array.

      i want to know if i pass address of char array then how that function definition get look like means how function catch that argument. how it store data into that array with example code.

      Chris KawaC 1 Reply Last reply
      0
      • M Offline
        M Offline
        mpergand
        wrote on last edited by mpergand
        #8
        void setStr(char* str)
        {
            std::strcpy(str,"hello");
        }
        
            char str [30];
        
            setStr(str);
            std::printf("%s\n",str);
        

        A more secure version:

        const int MAXLENGTH=30;
        
        void setStr(char* str)
        {
            std::strncpy(str,"hello",MAXLENGTH);
        }
        
            char str [MAXLENGTH+1];  // MAXLENGTH + ending zero
        
            setStr(str);
            std::printf("%s\n",str);
        
        Q 1 Reply Last reply
        2
        • M mpergand
          void setStr(char* str)
          {
              std::strcpy(str,"hello");
          }
          
              char str [30];
          
              setStr(str);
              std::printf("%s\n",str);
          

          A more secure version:

          const int MAXLENGTH=30;
          
          void setStr(char* str)
          {
              std::strncpy(str,"hello",MAXLENGTH);
          }
          
              char str [MAXLENGTH+1];  // MAXLENGTH + ending zero
          
              setStr(str);
              std::printf("%s\n",str);
          
          Q Offline
          Q Offline
          Qt embedded developer
          wrote on last edited by Qt embedded developer
          #9

          @mpergand @jsulm @Chris-Kawa thanks

          #include <stdio.h>
          #include <string.h>
          #define byte    unsigned char 
          
          void print (byte *a)
          {
          
          strcpy(a,"abcdefghijklmnopqrstuvwxyz");
          printf("parsed pointer %s",a);
          
              
          }
          
          
          int main()
          {
              byte str [27],CardCategory[5];
          
              print(&str);
             memset(CardCategory,0x00,sizeof(CardCategory));
             memcpy(&CardCategory[0],&str[0],2); // here i am expecting that str[0] and str[1] get 
           //copied into card category  str  
           printf("\n hi %s",CardCategory);
          
              return 0;
          }
          
          M 1 Reply Last reply
          0
          • Q Qt embedded developer

            @mpergand @jsulm @Chris-Kawa thanks

            #include <stdio.h>
            #include <string.h>
            #define byte    unsigned char 
            
            void print (byte *a)
            {
            
            strcpy(a,"abcdefghijklmnopqrstuvwxyz");
            printf("parsed pointer %s",a);
            
                
            }
            
            
            int main()
            {
                byte str [27],CardCategory[5];
            
                print(&str);
               memset(CardCategory,0x00,sizeof(CardCategory));
               memcpy(&CardCategory[0],&str[0],2); // here i am expecting that str[0] and str[1] get 
             //copied into card category  str  
             printf("\n hi %s",CardCategory);
            
                return 0;
            }
            
            M Offline
            M Offline
            mpergand
            wrote on last edited by mpergand
            #10

            @Qt-embedded-developer said in I want to know where i made mistake because memcpy not copy "ab" of char array into my CardCategory variable ?:

            print(&str);

            shoudn't compile !

            Arrays are passed by address

            1 Reply Last reply
            0
            • Q Qt embedded developer

              @jsulm @Chris-Kawa @mpergand but i have to understand code where i pass address of unsigned char array in function. that function catch this address. store the data like "abcdef" into that array.

              i want to know if i pass address of char array then how that function definition get look like means how function catch that argument. how it store data into that array with example code.

              Chris KawaC Offline
              Chris KawaC Offline
              Chris Kawa
              Lifetime Qt Champion
              wrote on last edited by Chris Kawa
              #11

              @Qt-embedded-developer said:

              i want to know if i pass address of char array then how that function definition get look like means how function catch that argument. how it store data into that array with example code.

              So there's multiple of ways to do that. They differ in details but achieve the same thing.

              // Takes a pointer to the first character, doesn't know the data is an array or how long it is.
              // Can lead to bugs like write past array or if someone passes null
              // You'd call it like this: print1(str);
              void print1(byte* a) 
              {
                  std::strcpy(a, "version_1");
              }
              
              // Takes an array by value, which pretty much means copies a pointer to the beginning of the data, but also enforces the length of the array
              // You'd call it like this: print2(str);
              void print2(byte a[27])
              {
                  std::strcpy(a, "version_2");
              }
              
              // Takes a reference to the first character, pretty much same as 1, but can't be null
              // Since a is a reference you need to take its address &a to write the data
              // You'd call it like this: print3(*str)   - * dereferences the first character
              void print3(byte& a)
              {
                  std::strcpy(&a, "version_3");
              }
              
              // Takes a pointer to an array of 27 elements. Someone could pass null here, so you should check for that before copying
              // Since arrays are basically fancy pointers themselves this is like a pointer to a pointer to first element
              // Since you get a pointer you need to use *a to get the thing it points to (pointer to first element)
              // You'd call it like this: print4(&str) 
              void print4(byte (*a)[27])
              {
                  std::strcpy(*a, "version_4");
              }
              
              // Takes a reference to an array of 27 elements. Pretty much same as 4, but can't be null
              // You'd call it like this: print5(str) 
              void print5(byte (&a)[27])
              {
                  std::strcpy(a, "version_5");
              }
              
              1 Reply Last reply
              3
              • S Offline
                S Offline
                SimonSchroeder
                wrote on last edited by
                #12

                I don't agree on everything with everybody else. If I am not mistaken, print(byte *a[]) and the corresponding call print(&str); are proper C++ (haven't tested it). The main problem seems to be with the implementation of your print function. I am not sure what the assignment to a actually does.

                Your definition of print requires an array of byte pointers. This only works in so far as for C and C++ pointers and arrays are kind of the same (not exactly the same, but the same in this context). The only reason to take the address of your buffer str[27] is to change the memory. Otherwise you should write your function in a way that you just pass in str: print(byte *a) or print(byte a[]) with a call print(str) (even better: also provide the size of the array!!!). @Chris-Kawa provided enough examples how to properly implement print.

                The other thing is that you seem to be using C++. You should try to use the string class once you got the data. So, in your short example, this would be:

                int main()
                {
                    byte str[27];
                    print(str);
                
                    std::string CardCategory(str, 2);
                    printf("\n %s", CardCategory.c_str());
                
                    return 0;
                }
                
                jsulmJ Chris KawaC Q 3 Replies Last reply
                1
                • S SimonSchroeder

                  I don't agree on everything with everybody else. If I am not mistaken, print(byte *a[]) and the corresponding call print(&str); are proper C++ (haven't tested it). The main problem seems to be with the implementation of your print function. I am not sure what the assignment to a actually does.

                  Your definition of print requires an array of byte pointers. This only works in so far as for C and C++ pointers and arrays are kind of the same (not exactly the same, but the same in this context). The only reason to take the address of your buffer str[27] is to change the memory. Otherwise you should write your function in a way that you just pass in str: print(byte *a) or print(byte a[]) with a call print(str) (even better: also provide the size of the array!!!). @Chris-Kawa provided enough examples how to properly implement print.

                  The other thing is that you seem to be using C++. You should try to use the string class once you got the data. So, in your short example, this would be:

                  int main()
                  {
                      byte str[27];
                      print(str);
                  
                      std::string CardCategory(str, 2);
                      printf("\n %s", CardCategory.c_str());
                  
                      return 0;
                  }
                  
                  jsulmJ Offline
                  jsulmJ Offline
                  jsulm
                  Lifetime Qt Champion
                  wrote on last edited by
                  #13

                  @SimonSchroeder said in I want to know where i made mistake because memcpy not copy "ab" of char array into my CardCategory variable ?:

                  I am not sure what the assignment to a actually does

                  It does not compile because of incompatible types :-)

                  https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • S SimonSchroeder

                    I don't agree on everything with everybody else. If I am not mistaken, print(byte *a[]) and the corresponding call print(&str); are proper C++ (haven't tested it). The main problem seems to be with the implementation of your print function. I am not sure what the assignment to a actually does.

                    Your definition of print requires an array of byte pointers. This only works in so far as for C and C++ pointers and arrays are kind of the same (not exactly the same, but the same in this context). The only reason to take the address of your buffer str[27] is to change the memory. Otherwise you should write your function in a way that you just pass in str: print(byte *a) or print(byte a[]) with a call print(str) (even better: also provide the size of the array!!!). @Chris-Kawa provided enough examples how to properly implement print.

                    The other thing is that you seem to be using C++. You should try to use the string class once you got the data. So, in your short example, this would be:

                    int main()
                    {
                        byte str[27];
                        print(str);
                    
                        std::string CardCategory(str, 2);
                        printf("\n %s", CardCategory.c_str());
                    
                        return 0;
                    }
                    
                    Chris KawaC Offline
                    Chris KawaC Offline
                    Chris Kawa
                    Lifetime Qt Champion
                    wrote on last edited by
                    #14

                    @SimonSchroeder said:

                    I don't agree on everything with everybody else. If I am not mistaken, print(byte *a[]) and the corresponding call print(&str); are proper C++ (haven't tested it).

                    It is proper C++, but not the right thing here, so it doesn't compile. byte* a[] is an array of pointers to bytes (read as (byte*) a[] ). That's valid C++ syntactically but you can't pass a pointer to an array of bytes &str to a parameter like that. Those are two different and unrelated types.

                    1 Reply Last reply
                    2
                    • S SimonSchroeder

                      I don't agree on everything with everybody else. If I am not mistaken, print(byte *a[]) and the corresponding call print(&str); are proper C++ (haven't tested it). The main problem seems to be with the implementation of your print function. I am not sure what the assignment to a actually does.

                      Your definition of print requires an array of byte pointers. This only works in so far as for C and C++ pointers and arrays are kind of the same (not exactly the same, but the same in this context). The only reason to take the address of your buffer str[27] is to change the memory. Otherwise you should write your function in a way that you just pass in str: print(byte *a) or print(byte a[]) with a call print(str) (even better: also provide the size of the array!!!). @Chris-Kawa provided enough examples how to properly implement print.

                      The other thing is that you seem to be using C++. You should try to use the string class once you got the data. So, in your short example, this would be:

                      int main()
                      {
                          byte str[27];
                          print(str);
                      
                          std::string CardCategory(str, 2);
                          printf("\n %s", CardCategory.c_str());
                      
                          return 0;
                      }
                      
                      Q Offline
                      Q Offline
                      Qt embedded developer
                      wrote on last edited by
                      #15

                      @SimonSchroeder said in I want to know where i made mistake because memcpy not copy "ab" of char array into my CardCategory variable ?:

                      The only reason to take the address of your buffer str[27] is to change the memory.

                      The only reason to take the address of your buffer str[27] is to change the memory.

                      S M 2 Replies Last reply
                      0
                      • Q Qt embedded developer

                        @SimonSchroeder said in I want to know where i made mistake because memcpy not copy "ab" of char array into my CardCategory variable ?:

                        The only reason to take the address of your buffer str[27] is to change the memory.

                        The only reason to take the address of your buffer str[27] is to change the memory.

                        S Offline
                        S Offline
                        SimonSchroeder
                        wrote on last edited by
                        #16

                        @Qt-embedded-developer said in I want to know where i made mistake because memcpy not copy "ab" of char array into my CardCategory variable ?:

                        The only reason to take the address of your buffer str[27] is to change the memory.

                        Maybe, I should be a little clearer: You can then change the memory address. If you just want to change the contents of the array, you don't need the address of the array. BTW, you should not change the address of something allocated on the stack. This is clearly not a use case to use the address to an array.

                        1 Reply Last reply
                        0
                        • Q Qt embedded developer

                          @SimonSchroeder said in I want to know where i made mistake because memcpy not copy "ab" of char array into my CardCategory variable ?:

                          The only reason to take the address of your buffer str[27] is to change the memory.

                          The only reason to take the address of your buffer str[27] is to change the memory.

                          M Offline
                          M Offline
                          mpergand
                          wrote on last edited by
                          #17

                          @Qt-embedded-developer

                          An example how to set a pointer by passing a double pointer:

                          void setStrAlloc(char** s)  // double pointer
                          {
                              const char msg[]="hello";
                          
                              *s=(char*)malloc(sizeof(msg));    // allocate/initialyze str pointer (*s)
                              std::strncpy(*s,"hello",sizeof(msg));
                          }
                          
                              char *str;  // uninitialized pointer
                              setStrAlloc(&str);  // pass address of pointer
                              std::printf("%s\n",str);
                          
                              free(str);  // free memory allocated by setStrAlloc
                          

                          It's a 'how to' example; not very usefull in practice.

                          I see you're using sizeof to know the size of a char array,
                          be aware that it doesn't work with pointers to char array:

                          const char msg[]="hello world";
                          std::printf("%ld\n",sizeof(msg)); // size=12 ->correct

                          ...
                          const char* msg_pt="hello world";
                          std::printf("%ld\n",sizeof(msg_pt)); // size=8 -> size of a pointer

                          In this case you need to use strlen() to know the size of the char array.

                          1 Reply Last reply
                          1

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved