C "Error: Invalid initializer" - c

the following short code snippet results in a invalid initializer error, and as a beginner in C, I do not understand why.
unsigned char MES[] = { 0x00, .... };
unsigned char *in[] = &MES;
Is this not the correct way to do it?

&MES is a pointer to an array of unsigned char.
in is an array of pointers to unsigned char.
Try instead :
unsigned char (*in)[] = &MES;
which makes in also a pointer to an array of unsigned char.

I think that what you are trying to achieve is the following:
unsigned char MES[] = { 0x00 };
unsigned char *in = MES;
qualifying in as an array (whose size is unknown) as follow
unsigned char (*in2)[] = &MES;
is not going to add valuable information to it aside that it has a finite size (which is true for any data) and if you print in and in2
printf ("%lx\n", (long unsigned int) in);
printf ("%lx\n", (long unsigned int) in2);
the value shall be the same.
Don't confuse the position of the data with the position of its reference.
Using &MES is like trying to read the position in memory where the position of the array is written. But this does not exist.
Consider the counterexample:
void *reference_to_memoryarea = malloc(3);
void **reference_to_the_reference = &reference_to_memoryarea;
Here the position exists and has a position in memory, where it is stored. And you can write into *reference_to_the_reference and generate a good leak

Related

How can I store 0xFF to a char in C?

How can I store something in this format: "0xff" to a char array after declaring the array. I'll demonstrate what I mean below.
When writing a code such as this, works just fine:
int main (void){
unsigned char array[] = {0xff,0xa4};
return 0;
}
But, what I need is slightly more complicated. I need to assign something such as 0xff to the array after having already declared it. How can I get this to work and obtain the exact same result as in the piece of code above? With the code below I keep receiving the error "multi-character character constant [-Wmultichar]" and "large integer implicitly truncated to unsigned type [-Woverflow]".
int main(void){
unsigned char array[2];
array[0] = '0xff';
array[1] = '0xa4';
return 0;
}
Use array[0] = '\xff'; to set a single char to a hex numerical.
Or array[0] = 0xff; as you did in the first part of your code, successfully.

How do I store an unsigned short into a char array? C language

I'm a beginner in C language, I was wondering how I store an unsigned short into a char array?
unit16_t is unsigned short, and below is my code.
uint16_t combined = 1234;
char echoPrompt[] = {combined};
EDIT:
Sorry for being unclear
I need echoPrompt to be a char array and combined needs to be an integer. I am passing echPrompt as a char array to a UART_write which required a char array.
You cannot pass an array to a function. You can pass a pointer. Pointers are not arrays.
If your UART_write looks anything like any of the standard C/POSIX functions write, fwrite etc, you need
result = UART_write (...,
(char*)&combined,
sizeof(combined), ...);
There is no need in a char array.
if I understood correctly, you want to save each upper and lower 1 byte of short in char array.
well, why don't you just use union?
typedef struct uint16_s{
char upper;
char lower;
} uint16_s;
typedef union uint16_u{
uint16_s sBuf;
uint16_t tBuf;
} uint16_u;
uint16_u combined;
combined.tBuf = 1234;
char echoPrompt[] = {combined.sBuf.upper, combined.sBuf.lower};

C Character from literal Splint warns of incompatible types

I have a program that uses unsigned chars to represent integers with a small range. I find myself needing to clear them to 0 in several different parts of the program, I have also recently started using splint and apparently:
unsigned char c = 0;
gives the warning:
Variable c initialized to type int, expects unsigned char: 0
Types are incompatible.
As there is no suffix for a literal char, How is it best to resolve this? I think I have a few options:
1: Ignore the warning.
2: Cast every time:
unsigned char c = (unsigned char)0;
3: Make a var to cut down the length of the code:
unsigned char uc_0 = (unsigned char)0;
unsigned char c = uc_0;
4: A function:
static inline unsigned char uchar(int in)
{
return (unsigned char)in;
}
unsigned char c = uchar(0);
splint has an option +charint that will treat char int as interchangeable.
You can ignore the warnings and use
unsigned char = 0;
In many cases when there is integer operation in order to save memory instead of using int which obviously consumes extra memory than char people do make use of unsigned char.
unsigned char i = 10;
unsigned char j = 1;
unsigned char k = i +j;
printf("%d",k);

How do you convert an unsigned int[16] of hexidecimal to an unsigned char array without losing any information?

I have a unsigned int[16] array that when printed out looks like this:
4418703544ED3F688AC208F53343AA59
The code used to print it out is this:
for (i = 0; i < 16; i++)
printf("%X", CipherBlock[i] / 16), printf("%X",CipherBlock[i] % 16);
printf("\n");
I need to pass this unsigned int array "CipherBlock" into a decrypt() method that only takes unsigned char *. How do correctly memcpy everything from the "CipherBlock" array into an unsigned char array without losing information?
My understanding is an unsigned int is 4 bytes and unsigned char 1 byte. Since "CipherBlock" is 16 unsigned integers, the total size in bytes = 16 * 4 = 64 bytes. Does this mean my unsigned char[] array needs to be 64 in length?
If so, would the following work?
unsigned char arr[64] = { '\0' };
memcpy(arr,CipherBlock,64);
This does not seem to work. For some reason it only copies the the first byte of "CipherBlock" into "arr". The rest of "arr" is '\0' thereafter.
An int is at least 16 bits, same as a short in that regard.
It looks like every unsigned int has values 0-255 or 00-FF in your case, which is a safe range for an unsigned char. However, the proper way to convert one to the other is a cast:
for (int i=0; i<16; ++i) arr[i] = (unsigned char) CipherBlock[i];
But you have not specified what kind of data decrypt() expects. From the signature, I suspect integral data (strings are usually char* or const char*) but it's hard to be sure without a context.
Note that you could also do printf("%02X", CipherBlock[i]); for printing.
Why don't you just cast the CipherBlock pointer to unsigned char * and pass that?
decrypt((unsigned char *)CipherBlock);
You need to repack the numbers so you can not use memcpy or cast it directly. Aib has it correct.
unsigned char array[16];
for(int i = 0; i < 16; i++) {
array[i] = CipherBlock[i];
}

Sizeof next byte in byte array

I have an unsigned char and I add integers to it but I want to get the sizeof next byte (i.e sizeof unsigned short int or unsigned int and so on).
The following code demonstrates what I want:
#include <stdio.h>
static void write_ushort(unsigned char *b, unsigned short int value) { b[1] = value >> 8; b[0] = value; }
static void write_ulong(unsigned char *b, unsigned long int value) { write_ushort(b + 2, value >> 16); write_ushort(b, value); }
static unsigned short int read_ushort(const unsigned char *b) { return b[1] << 8 | b[0]; }
static unsigned long int read_ulong(const unsigned char *b) { return read_ushort(b + 2) <<16 | read_ushort(b); }
int main() {
unsigned char b[2];
unsigned int v0; /* 4 */
unsigned short int v1; /* 2 */
v0 = 200; v1 = 1235;
write_ushort(&b[0], v0); write_ulong(&b[1], v1);
/* what i expect printf to output is:
* 4 2
* but it obviously outputs 1 1 */
printf("%d %d\n", read_ushort(&b[0]), read_ulong(&b[1]));
printf("%d %d\n", (int)sizeof(b[0]), (int)sizeof(b[1]));
return 0;
}
This isn't possible. The sizeof operator will return the size of a type, or the size of the declared type of a variable. You can't massage anything else out of it, and your code won't keep track of what type of variable a number was stored in before you assigned it to a new variable.
Regardless of the type of v0 or v1, when they're stored in elements of your array, they are converted to unsigned char.
If you want 4 2 as output, you'll need to pass sizeof(v0) and sizeof(v1) to printf, or keep track of this some other way.
C is statically typed, and you can't just change the data type of a variable (or array) by assigning something to it. In fact you can't change the data type of a variable at all: a variable corresponds (almost exactly) to a certain chunk of memory with its size defined at compile time. You can cast variables so that they are treated as though they were a different type for a specific operation, but the chunk of memory is the same size always.
And, since a variable is just a block of memory there is no way for the computer (or compiler) to know that you are using a char[2] array to store a short or a long. You have to keep track of this yourself.
Here is a major problem:
write_ulong(&b[1], v1);
You take the second byte (of a two-byte array) and pass it to write_ulong where it's handled as an array of four bytes. This means you are writing several bytes beyond the original array b and overwrite the stack. This is undefined behavior and will make your program behave very strange.

Resources