C/CAPL defining one array from another - c

this is my first question here, please notice I'm very new to coding. Quick search doesn't helped me since I think the answer might be too simple.
Im writing some code in CAPL (a CANoe specific language based on C).
Lets have my scenario simplified: I have to read 10 values Input, but I'm just able to read one by a time (due to HW reasons).
My value is stored in a buffer (rsBuf), now I'm trying to define a help-array for everytime I read the value (rsBuf1 ... 10).
At the end I will create another array with added values of rsBuf1 ... rsBuf10.
for every "read-action", I want to define
rsBuf1 = rsBuf;
rsBuf2 = rsBuf; and so on...
error: for "rsBuf1 = rsBuf;" Error 1112 at (732,16): operand types are incompatible.
Compilation failed -- 1 errors, 0 warnings
my "real" values:
variables
{
byte rsBuf[1024];
byte rsBuf1[1024];
}
is there an easy way to do this one-array-from-another?
I also tried some other notations I found, like rsBuf1 = {rsBuf}, but wasn't helping. Of course I could define
rsBuf1[1]=rsBuf[1];
...
rsBuf1[1024]=rsBuf[1024];
but that would be a waste of time I guess.
Thanks in advance, cheers Robert

You can't copy arrays through assignment in C, because the syntax does not allow it. The best solution is to use the memcpy function.
Alternatively, if it makes sense for the program design, you could put the arrays inside a wrapper struct:
typedef struct
{
int array [5];
} array_wrapper_t;
array_wrapper_t this = {1,2,3,4,5};
array_wrapper_t that;
that = this;
This should yield identical machine code as a call to memcpy.

Option 1
You can use memcpy as follows to copy the entire array:
memcpy(rsBuf1, rsBuf, elcount(rsBuf));
The following would copy the first four bytes:
memcpy(rsBuf1, rsBuf, 4);
Option 2
Optionally you could define your copy-function, see the copy_buffer() implementation:
variables
{
byte rsBuf[1024] = {1, 2, 3, 4, 5, 6, 7, 8};
byte rsBuf1[1024];
}
on start
{
print_buffer(rsBuf, 8);
print_buffer(rsBuf1, 8);
copy_buffer(rsBuf1, rsBuf, elcount(rsBuf));
print_buffer(rsBuf1, 8);
}
void copy_buffer(byte dest[], byte src[], long len)
{
int i;
for (i = 0; i < len; i++)
dest[i] = src[i];
}
void print_buffer(byte buf[], byte len)
{
int i;
writeLineEx(0, 0, ">");
for (i = 0; i < len; i++)
writeEx(0, 0, " 0x%02x", buf[i]);
}

Related

How can I use malloc from a function?

I am trying to understand how malloc works. I did a program searches for the largest element in a one dimensional array int.
This is the code.
#include <stdlib.h>
#include <stdio.h>
void largest_element(int *nbr)
{
int i;
int n;
int m;
i = 1;
nbr = (int*)malloc(sizeof(nbr) + 8);
while (i < 8)
{
if (*nbr < *(nbr + i))
*nbr = *(nbr + i);
i++;
}
printf("%d ", *nbr);
}
int main(void)
{
int i;
int tab[8] = {11, 2, 4, 5, 9, 7, 8, 1};
int n = sizeof(tab)/sizeof(int);
i = 0;
largest_element(&tab[8]);
return(0);
}
The program works without malloc but how can I make it work with malloc? What did I do wrong and why does my code only give me garbage numbers?
I think you are lost with pointers and arrays so you can not understand malloc properly (no offense, everyone who is learning C do the same mistake).
Let's take your main function. When you run:
int tab[8] = {11, 2, 4, 5, 9, 7, 8, 1};
You staticly allocate an array of 8 integers and you fill it with your numbers.
The dynamic equivalent would be:
int* tab = malloc(sizeof(int) * 8);
tab[0] = 11;
tab[1] = 2;
/// Etc...
tab[7] = 1;
First thing: the first element of an array has the index 0. So in your largest_element function, i should be initialized at 0 instead of 1.
The reason is, when you deal with array, you deal with pointers. In your case, tab is a pointer to the first element of the array. So, when you do tab[3], you get the forth element of your array.
Second thing: when you do:
largest_element(&tab[8]);
You send to your function the eighth element after the begining of your array. The problem is: you do not own this memory area! You own the memory only until tab[7].
If you want to send the complete array to your function, just use:
largest_element(tab);
Now, let's talk about your largest_element function.
You do not need to call malloc here since the memory is already allocated
When you do *nbr = *(nbr + i); you change the value of the first element of your array. I think you wanted to do m = *(nbr + i); isn't it.
Why do you not use the nbr[i] instead of *(nbr + i)?
A correct implementation of this function would be something like (not tested):
void largest_element(int *nbr)
{
int i = 0;
int max = 0;
while (i < 8)
{
if (max < nbr[i])
max = nbr[i];
i++;
}
printf("%d ", m);
}
A last thing, using malloc involve using the function free to release the memory when you do not need it anymore.
What did I do wrong and why does my code only give me garbage numbers??
In largest_element(int *nbr) nbr points to the array tab in main (at least if you call it like this: largest_element(tab); instead of like this largest_element(&tab[8]);
Then you call nbr = (int*)malloc(sizeof(nbr) + 8); now nbr points to some allocated memory which has not been initialized and which contains garbage values. Now if you read from that memory it's normal that you get garbage values.
You simply don't need malloc for this problem, just as you don't need floating point math or file system related functions for this problem.

Is it possible to use an array within a for loop?

This my code as it stands:
int sliderNum; // Variable Declaration //
// Loop Sequencer //
for (sliderNum = 41; sliderNum <= 48; sliderNum = sliderNum + 1)
However I need to change this so the loop no longer counts from 41-48 but instead counts e.g 73,71,34,46,52,4,17 etc. So a specific set of numbers one after another but not like counting normally.....hope that makes sense.
As you can probably tell, I'm pretty new to this programming stuff so any help would be greatly appreciated.
Cheers.
int a[] = {1,4,7,10};
for(int i=0; i<sizeof(a)/sizeof(a[0]); ++i)
{
....process a[i]
}
I recommend consulting a good book on c.
Regarding the code: This is basically looping over an array with iterations = size in bytes of the array / size in bytes of an element of array
You might even place the array literally within the for loop definion. This way, it somewhat resembles "with" statement, that is common in Python:
#define ARRAY_LEN(a) (sizeof(a)/sizeof(*a))
int main()
{
for (int a[] = {73, 71, 34, 46, 52, 4, 17}, i = 0; i < ARRAY_LEN(a); i++) {
// ...
}
}
Personally, I wouldn't write such code on production, as it may be questioned as "too clever", whereas putting the array at the top of loop seems to make it more readable.

unsigned char table length

I declared a table of unsigned char as follow:
unsigned char buf[10]={'1','5',0x00,'8'};
in order to know the number of elements of this table i implemented this function
int tablength(unsigned char *buf)
{
int i=0;
for (i=0;buf[i];i++)
;
return i;
}
However this function don't give me the right result when the buffer contains 0 in the middle .Sizeof don't give me the right result since it returns 10 in this case i can't neither use strlen since this is a table of unsigned char.
Do you have any idea to improve this function or any predefined function that help me solve my problem (the result that i 'am waiting for is 4)
Technically, since you declared a statically allocated array of 10 elements, the size of the array is 10. Even though you may not have initialized every element, there is something filling that space. C++ cannot determine whether the value in the array means anything or not.
After
unsigned char x[10] = {1, 2, 3};
the variable x (an array) has 10 elements, the first three initialized to 1, 2 and 3 and all the others initialized to 0. In other words that definition is absolutely identical to
unsigned char x[10] = {1, 2, 3, 0, 0, 0, 0, 0, 0, 0};
An array in C and C++ is just a fixed area of memory and doesn't include a counter of how many "interesting" elements are there.
If you are looking for a container with a variable number of elements consider instead std::vector (C++ only). With that std::vector::size() returns the current number of elements in the container.
If you need the array to contain exactly the number of elements you've specified, just declare it without a specific size:
unsigned char buf[]={'1','5',0x00,'8'};
cout << sizeof(buf); // should be 4
If you want to store a variable amount of data (in C++) use std::vector instead of an array.
Otherwise you'll need to keep track of the number of valid elements yourself. There's nothing in the language that will do it for you.
Compilers cannot know how you would like to use an array instance.
Therefore you must follow the language's semantics. By declaring your array globally or locally, but with the storage class specifier static you are initializing every element to 0 on default and your function will work.
0x00 is false. 0x00 (which same as 0x0) is a hex number representing 0 (false). This is where your counting loop will stop at - the 3rd element.
Another thing you can do is declare your array with non-fixed size.
unsigned char buf[]={'1','5',0x00,'8'};
In that case, the sizeof operator works as expected.
Because that way, you will have an array of 4 elements.
strlen() obviously won't work as it is designed to work with strings, not a buffer.
As for a function that counts on a smarter way:
size_t arrcnt (unsigned char source[], size_t size)
{
size_t i;
for(i = size; i >= 0 && !source[i]; i--);
return i + 1;
}
Usage:
printf("size of buf: %u", arrcnt(buf, sizeof(buf));
buf[i] evaluates to false when buf[i] contains 0.
You cannot do what you want unless you know one value which can never occur in your array between 0 to UCHAR_MAX (255). Say the value is 255, then you first preinitialize the full array to 255 before you start filling it up.
memset(buf, 255, sizeof(char) * sizeof(buf));
Then you fill other elements like you want and then you can use the following
for(i = 0; buf[i] != 255, ++i)
try putting :
for(int i=0;buf[i]!= 0;i++)
count++;
return count;

How to use memset for initializing bufffers with values other than 0? [duplicate]

This question already has answers here:
Why is memset() incorrectly initializing int?
(9 answers)
Closed 9 years ago.
int buff[1000]
memset(buff, 0, 1000 * sizeof(int));
will initialize buff with o's
But the following will not initialize buff with 5's. So what is the way to achieve this using memset in C (not in C++)? I want to use memset for this purpose.
int buff[1000]
memset(buff, 5, 1000 * sizeof(int));
memset initializes bytes, not data types, to a value. So for your example…
int buff[1000]
memset(buff, 5, 1000 * sizeof(int));
… if an int is four bytes, all four bytes will be initialized to 5. Each integer will actually have a value of 0x05050505 == 84215045, not 5 as you're expecting.
If you would like to initialize each integer in your array to 5, you'll have to do it like this:
int i;
for(i = 0; i < 1000; i++)
buff[i] = 5;
Depending on what OS you are using you may be able to use memset_pattern4 et al, otherwise you'll just need to do it with a loop.
I personally don't recommend memset for general initialization. There are too many things you have to be sure of to be able to correctly and portably use it. It's basically only good for char arrays or microcontroller code.
The way to initialize an array in C is the following (assume size N):
for (i = 0; i < N; ++i)
buff[i] = init_value;
With C99, you can do more interesting stuff. For example, imagine the buffer is an array of the following struct:
struct something
{
size_t id;
int other_value;
};
Then you can initialize like this:
for (i = 0; i < N; ++i)
buff[i] = (struct something){
.id = i
};
This is called designated initializer. Like all other cases of initializers, if you don't mention a specific field of the struct, it will be automatically zero initialized.
If buff isn't an array of bytes, you can only initialise it to values which consist of repetitive hex values using memset (e.g. -1, 0x01010101, etc)
One way to do this is to use memcpy, thus:
buff[0] = 5;
memcpy(buff + 1, buff, sizeof(buff) - sizeof(*buff))
HOWEVER this relies on undefined behaviour and might or might not work on your system.
A decent compiler should produce an efficient enough loop from
for (i = 0; i < 1000; i++) buff[i] = 5;

Trying to print form array or array addresses...not getting it?

new here, trying to learn a piece of C with the great help of you guys, this could be a basic questions here....sorry you have start from basic.
void main()
{
char* arr[3] = {"baba","tata","kaka"};
char* arr1[3] = {"baba1","tata1","kaka1"};
char* arr2[3] = {"baba2","tata2","kaka2"};
char** array_all[] = {arr,arr1,arr2};
printf("%s\n",*array_all[0]);
//please guide me how to access individual entity(as arr[1], arr1[2],arr3[1]) //from each array using array_all
}
I'm not sure if this is exactly what you were looking for.. but this is what I understand so far.
You are wanting to access the individual elements of array_all (the elements arr, arr1 and arr2)? If so then all you do is...
array_all[0][i];
Where i is the element that you want to access.
The reason for this is because the index operators ([ and ]) actually dereferences a pointer and offsets the pointer (as in adds it by some integer, i.e. you move down in memory) that you specify. I recommend reading up on pointer arithmetic if you have no clue what happens if you add a pointer by some integer.
For example:
int x[] = { 1, 2, 3 };
// writing x[i] is the same as *(x + i)
int i = 2; // the element you wish to access
*(x + i) = 4; // set the ith (3rd) element to 4
*(x + 1) = 43; // set the 2nd element to 43
// Therefore...
// x now stores these elements:
// 1, 43, 4
// proof: print out all the elements in the array
for(int i = 0; i < 3; ++i)
{
printf("x[%i]=%i\n", i, x[i]);
}
Also, writing x[0] is the same as writing *x, since the array name actually points to the first element of the array.
OH and one thing, main should actually return an integer result. This is mainly used for error checking in your program, 0 usually means no error occurred and every other error-code (number other than 0) is some specific error related to your program, that you can choose.
i.e.
int main()
{
// e.g. for an error code
/*
if(someErrorOccured)
{
return SOME_ERROR_OCCURED_RETURN_VALUE;
}
*/
return 0; // this is at the end of the function, 0 means no error occured
}
change your printf statement line with this..
printf("%s\n",array_all[i][j]);
In place of i keep your array number and in place of k give your required element number. It works.

Resources