I want to know where i made mistake because memcpy not copy "ab" of char array into my CardCategory variable ?
-
wrote on 4 Jul 2022, 10:30 last edited by Qt embedded developer 7 Apr 2022, 13:59
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 useprintf("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();
-
wrote on 4 Jul 2022, 14:41 last edited by mpergand 7 Apr 2022, 14:44
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);
-
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 useprintf("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();
@Qt-embedded-developer In the code you posted you did not put any characters into str...
-
@Qt-embedded-developer In the code you posted you did not put any characters into str...
wrote on 4 Jul 2022, 12:27 last edited by Qt embedded developer 7 Apr 2022, 12:29@jsulm i used to print function to copy "abcdefghijklmnopqrstuvwxyz" into str. is it wrong ? how to make it right using caching char array though pointer ?
-
Lifetime Qt Championwrote on 4 Jul 2022, 12:33 last edited by Chris Kawa 7 Apr 2022, 12:36
Is it even compiling for you? Which compiler do you use? This has some invalid syntax.
But anyway...#define byte unsigned char
- this is very very old style. In modern C++ such defines are replaced byusing
statement:using byte = unsigned char;
It looks like you want a pointer to an array of bytes as a parameter of
print
. What you have there is an array of pointers to byte. That's not the same. You can only have a pointer to an array of known size, so the parameter should beprint(byte (*a)[27])
. Yes, just by looking at this syntax you should be thinking you're doing something very very weird. You probably want a pointer to bytes there, so justprint(byte* a)
.a="abcdefghijklmnopqrstuvwxyz";
There's no assignment operator for arrays like that. If you want to fill the array with those characters you need to copy it, somemcpy(a, "abcdefghijklmnopqrstuvwxyz", 27)
. All in all this function is really weird. If all you want is an array of those characters than make it a constant:const byte* str = "abcdefghijklmnopqrstuvwxyz"
.printf("\n %s",CardCategory);
Remember that you only copied 2 characters. The rest of theCardCategory
array is still uninitialized (filled with garbage) and printf will print until a terminating null character, so this will printabSomeGarbageWhateverHappensToBeInTheMemoryThereOrItCouldCrashYourAppBecauseOfInvalidMemoryAccess
-
@jsulm i used to print function to copy "abcdefghijklmnopqrstuvwxyz" into str. is it wrong ? how to make it right using caching char array though pointer ?
@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. -
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 useprintf("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();
wrote on 4 Jul 2022, 13:03 last edited by@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);
-
@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.wrote on 4 Jul 2022, 14:04 last edited by Qt embedded developer 7 Apr 2022, 14:11@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.
-
wrote on 4 Jul 2022, 14:41 last edited by mpergand 7 Apr 2022, 14:44
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);
-
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);
wrote on 4 Jul 2022, 14:49 last edited by Qt embedded developer 7 Apr 2022, 14:52@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; }
-
@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; }
wrote on 4 Jul 2022, 15:10 last edited by mpergand 7 Apr 2022, 15:11@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
-
@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.
Lifetime Qt Championwrote on 4 Jul 2022, 17:47 last edited by Chris Kawa 7 Apr 2022, 17:52@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"); }
-
wrote on 5 Jul 2022, 06:56 last edited by
I don't agree on everything with everybody else. If I am not mistaken,
print(byte *a[])
and the corresponding callprint(&str);
are proper C++ (haven't tested it). The main problem seems to be with the implementation of yourprint
function. I am not sure what the assignment toa
actually does.Your definition of
print
requires an array ofbyte
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 bufferstr[27]
is to change the memory. Otherwise you should write your function in a way that you just pass instr
:print(byte *a)
orprint(byte a[])
with a callprint(str)
(even better: also provide the size of the array!!!). @Chris-Kawa provided enough examples how to properly implementprint
.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; }
-
I don't agree on everything with everybody else. If I am not mistaken,
print(byte *a[])
and the corresponding callprint(&str);
are proper C++ (haven't tested it). The main problem seems to be with the implementation of yourprint
function. I am not sure what the assignment toa
actually does.Your definition of
print
requires an array ofbyte
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 bufferstr[27]
is to change the memory. Otherwise you should write your function in a way that you just pass instr
:print(byte *a)
orprint(byte a[])
with a callprint(str)
(even better: also provide the size of the array!!!). @Chris-Kawa provided enough examples how to properly implementprint
.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; }
@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 :-)
-
I don't agree on everything with everybody else. If I am not mistaken,
print(byte *a[])
and the corresponding callprint(&str);
are proper C++ (haven't tested it). The main problem seems to be with the implementation of yourprint
function. I am not sure what the assignment toa
actually does.Your definition of
print
requires an array ofbyte
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 bufferstr[27]
is to change the memory. Otherwise you should write your function in a way that you just pass instr
:print(byte *a)
orprint(byte a[])
with a callprint(str)
(even better: also provide the size of the array!!!). @Chris-Kawa provided enough examples how to properly implementprint
.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; }
@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. -
I don't agree on everything with everybody else. If I am not mistaken,
print(byte *a[])
and the corresponding callprint(&str);
are proper C++ (haven't tested it). The main problem seems to be with the implementation of yourprint
function. I am not sure what the assignment toa
actually does.Your definition of
print
requires an array ofbyte
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 bufferstr[27]
is to change the memory. Otherwise you should write your function in a way that you just pass instr
:print(byte *a)
orprint(byte a[])
with a callprint(str)
(even better: also provide the size of the array!!!). @Chris-Kawa provided enough examples how to properly implementprint
.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; }
wrote on 5 Jul 2022, 10:14 last edited by@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.
-
@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.
wrote on 5 Jul 2022, 10:37 last edited by@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.
-
@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.
wrote on 5 Jul 2022, 11:56 last edited byAn 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 pointerIn this case you need to use strlen() to know the size of the char array.
1/17