Array slicing in C - c

In Python, if I wanted to assign the vector x=(1,2) to the first two elements of y=(0,0,0,0), I would do something like y[:1] = x. Is there an equivalent in C to assign a double x[2]={1.,2.} to the first two elements of an available double y[4] = {0.,0.,0.,0.}? Or will I have to loop?

Just try this
#include <string.h>
#include <stdio.h>
int main()
{
double x[2] = {1., 2.};
double y[4] = {0., 0., 0., 0.};
memcpy(y, x, 2 * sizeof(*x));
/* ^ 2 elements of size -> sizeof(double) */
return 0;
}
instead of writing sizeof(double) which is ok, i did sizeof(*x) because if I change the type of x I wouldn't need to fix the memcpy, but i would also have to change the type of y in that case.

You could write a function that passes in the pointer or array, an offset, and a length. The function then allocates space to a new pointer with malloc() and does a memcpy() operation or loop-and-copy, although memcpy() is probably better. The new pointer is returned to the caller.

Yes, it is possible using the function memcpy. But you have to be careful about data types. You can also copy data of one type to another. Again as I said, you need to be careful. Otherwise it may generate garbage value.
And second option is looping as mentioned in question.

Try this. A bit more low-level than your python method but welcome to C where sooner or later everything is block of raw memory to be shunted around!
The macro arraycopy applies some size checking.
The function arraycopyunchecked is fairly raw.
The functions are overlap safe. Under the hood they use memcopy(,,) which may be slower but won't have surprise results if unexpected aliasing results in overlapping arrrays.
#include <stdio.h>
#include <stdlib.h>
#include <string.h> //includes mempcy. I know! I know!
#define arraycopy(dest,doffset,source,soffset,count) arraycopy_((dest),(doffset),(source),(soffset),(count),sizeof(*(dest)),sizeof(*(source)))
int arraycopy_(void*const dest,const size_t doffset,const void*const source, const size_t soffset,const size_t count,const size_t size,const size_t sizecheck){
if(size!=sizecheck){
return 1;//Incompatible types.
}
memcopy(((char*)dest)+doffset*size,((const char*)source)+soffset*size,count*size);
return 0;
}
int arraycopyunchecked(void*const dest,const size_t doffset,const void*const source, const size_t soffset,const size_t count,const size_t size){
memcopy(((char*)dest)+doffset*size,((const char*)source)+soffset*size,count*size);
return 0;
}
int main(void) {
int errors=0;
double dest[]={0.0,0.0,0.0,0.0};
double source[]={1.0,2.0};
arraycopy(dest,0,source,0,2);
if(dest[0]!=1.0){
++errors;
}
if(dest[1]!=2.0){
++errors;
}
if(dest[2]!=0.0){
++errors;
}
arraycopy(dest,1,source,0,2);
if(dest[0]!=1.0){
++errors;
}
if(dest[1]!=1.0){
++errors;
}
if(dest[2]!=2.0){
++errors;
}
if(errors!=0){
printf("Errors - %d\n",errors);
}else{
printf("SUCCESS");
}
double dest1[]={0.0,0.0,0.0,0.0,0.0};
double source1[]={1.0,2.0,3.0};
arraycopy(dest1,2,source1,1,2);
if(dest[2]!=2.0){
++errors;
}
if(dest[3]!=3.0){
++errors;
}
return errors==0?EXIT_SUCCESS:EXIT_FAILURE;
}

Related

Is it illegal to modify the contents of the qsort's comparison function?

I did not find anything about this on the man page, but cppreference.com says:
The signature of the comparison function should be equivalent to the
following:
int cmp(const void *a, const void *b);
The function must not modify the objects passed to it and must return
consistent results when called for the same objects, regardless of
their positions in the array.
Would converting the strings with strtod, atof etc. come under modification and result in undefined behavior or so?
The objective is to sort an array of char * numerically. If it is illegal, do I have to write my own sort routine?
Converting the strings pointed to by the array elements using strtod or atof is perfectly fine because neither of these functions modify their argument strings. Note that the comparison function arguments of type const void * do not point to the strings in your example, they point to individual char * elements of the array, which it must not change. What these char * pointers point to should not be changed either as this might affect the result of further comparisons involving the same string pointers, producing inconsistent results, hence causing undefined behavior in qsort.
Here is an example:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int my_compare(const void *a, const void *b) {
char * const *sa = a;
char * const *sb = b;
double xa = strtod(sa, NULL);
double xb = strtod(sb, NULL);
return isnan(xa) ? (isnan(xb) ? 0 : 1) :
isnan(xb) ? -1 :
(xa > xb) - (xa < xb);
}
int main() {
char *array[] = { "1.0", "10.0", "2.0" };
size_t n = sizeof(array) / sizeof(array[0]);
qsort(array, n, sizeof array[0], my_compare);
for (size_t i = 0; i < n; i++)
printf("%s\n", array[i]);
return 0;
}
A function should only do what it says on the tin. In this case, it should only do a comparison.
To aid this, and to try to ensure that this is all that it does, it uses the keyword const.
So if necessary just take local copies of the data. In most (all?) this is usually not necessary.
EDIT
As strtod and atof do not modify the strings, they can be used.

How to terminate variable length array when all values are valid?

I'm passing an array of single-precision floating point values to a function in C. The function has no knowledge of the size of the array and I'd like to keep it that way, primarily because while the underlying array is of course fixed-length I won't always be filling it completely so I'd need to be able to find the end anyway. With a string you use a null-terminator, but with this implementation all possible values are potentially valid. Is the best I can do like a "code word" to mark the end using multiple values in order, something like ASCII 'STOP'? That leaves open the possibility of coincidentally having that code word in the array of valid data...
You'll see array/size pairs being passed around in C a lot, it's really the only way to do this reliably. Even C strings, which are NUL terminated, are often sent with a length parameter to be sure you don't inadvertently walk off the end of the array and into other memory.
This approach also permits you to use substrings, or subsets of the array, instead of being committed to use the whole thing, the problem you're basically trying to solve. Having a terminator is both a blessing and a curse, as anyone who's ever tried to battle a pernicious buffer-overflow bug can attest to.
In your case, the function signature should look like:
void process(float* v, size_t n)
Where v is the array of floating-point values to process and n is how many of them to use. n should be less than or equal to however many valid entries are in the v array.
If you're passing this kind of thing around a lot you may even encapsulate it in a simple struct that defines the data and size. You can then wrap around that some simple allocator/populator tools.
For example:
struct float_array {
float* values;
size_t size;
};
Where you can then define something like:
struct float_array* make_float_array(size_t n);
void free_float_array(struct float_array* f);
You don't need to pass the array maximum length, just the length currently being used for this call along with the pointer.
You can use NAN this way, assuming that's not a valid value for your dataset:
#include <math.h>
float average(float *array)
{
float sum = 0.0; // Declare this as double for better precision
size_t index = 0;
// x == NAN will return false for all x including NAN, so we need
// the function isnan()
while(! isnan(array[index]))
sum += array[index++];
return sum/index;
}
Since you're probably want to do this for many functions, I recommend writing a function for calculating length:
size_t farray_length(float *array)
{
size_t len = 0;
while(! isnan(array[len])) len++;
return len;
}
But the usual way of solving these problems in C is to send the size as a separate parameter.
float average(float *array, size_t size)
{
float sum = 0.0;
for(size_t i=0; i<size; i++)
sum += array[i];
return sum/size;
}
A third way, which can be useful for instance if you're coding a library with objects you don't want the user to mess with directly, is to declare a struct.
struct float_array {
float *array;
size_t size;
}
float average(float_array array) {
...
With a string you use a null-terminator, but with this implementation all possible values are potentially valid.
If all values are valid, a sentinel value cannot be implemented. It's as simple as that (which is why EOF is an integer value that overflows the char type).
The function has no knowledge of the size of the array and I'd like to keep it that way...
Assuming NaN is an invalid value, you could use the isnan() macro to test for a sentinel value.
However, is NaN is a valid value...
I'd need to be able to find the end anyway.
The only option left is to actually pass the array length along with the array.
If you can't add the array length as a separate argument, you could (probably) store the length of the array as the first member - either using a struct (recommended) or using type punning (don't try this at home unless you know what you're doing).
i.e.
typedef struct float_array_s {
unsigned int len;
float f[];
};
static unsigned int float_array_len(float_array_s * arr) { return arr->len; }
static float float_array_index(float_array_s * arr, unsigned int index) { return arr->f[index]; }
There's really no reason to use computation cycles if you can simply pass the length of the valid array length along with the array.
Edit (type punning)
I highly recommend avoiding this approach, since type lengths could cause hard to detect bugs. However...
It's possible to store the length of the array in the first float member, by using the same bytes (memory) to store an integer.
Note that this might crash (or worst, silently fail) if unsigned int is longer than float (which it might be, even though they usually have the same size in bytes).
i.e.
#include "math.h"
#include "stdint.h"
#include "stdio.h"
/* Returns the member at `index`. */
static float float_array_index_get(float *arr, unsigned int index) {
return arr[index + 1];
}
/* Sets the member at `index` to `val. */
static void float_array_index_set(float *arr, unsigned int index, float val) {
arr[index + 1] = val;
}
/* Returns the array's length. */
static unsigned int float_array_length_get(float *arr) {
if (sizeof(unsigned int) > sizeof(float)) {
fprintf(
stderr,
"ERROR: (%s:%d) type size overflow, code won't work on this system\n",
__FILE__, __LINE__);
}
union {
float f;
unsigned int i;
} pn;
pn.f = arr[0];
return pn.i;
}
/* Sets the array's length. */
static void float_array_length_set(float *arr, unsigned int len) {
if (sizeof(unsigned int) > sizeof(float)) {
fprintf(
stderr,
"ERROR: (%s:%d) type size overflow, code won't work on this system\n",
__FILE__, __LINE__);
}
union {
float f;
unsigned int i;
} pn;
pn.i = len;
arr[0] = pn.f;
}
/* Pushes a member to the array, increasing it's length. */
static void float_array_index_push(float *arr, float val) {
unsigned int len = float_array_length_get(arr);
float_array_index_set(arr, len, val);
float_array_length_set(arr, len + 1);
}
/* Pops a member from the array...
* ... returning nan if the member was nan or if the array is empty.
*/
static float float_array_index_pop(float *arr) {
unsigned int len = float_array_length_get(arr);
if (!len)
return nan("");
float_array_length_set(arr, len);
return float_array_index_get(arr, len);
}
P.S.
I hope you'll stick to the simple func(float * arr, size_t len) now that you see how much extra code you need just to avoid passing the length of the array.

Change Array without returning it [C]

I just have a basic question concerning arrays in functions.
I am trying to change an array in a function without returning it.
I know how to do this for integers or doubles but i didn't know how to do this for arrays. So i experimented a little bit and now I am confused.
I have 2 variations of my code which i thought should do the same thing , but they don't. I pass the array b to the function Test. In the function I try to fill the array with the values 0, 1 ,2
#include <stdlib.h>
#include <stdio.h>
void Test(int * vector){
vector = malloc(3*sizeof(int));
int i;
for(i=0;i<3;i++){
*(vector+i)=i;
}
}
int main(){
int b[3];
Test(b);
printf("%i\n",b[0]);
printf("%i\n",b[1]);
printf("%i\n",b[2]);
return EXIT_SUCCESS;
}
This Version doesnt work, i don't get the expected result 0,1,2
This Code on the other hand does seem to work:
#include <stdlib.h>
#include <stdio.h>
void Test(int * vector){
int * b = malloc(3*sizeof(int));
int i;
for(i=0;i<3;i++){
*(b+i)=i;
*(vector+i) = *(b+i);
}
}
int main(){
int b[3];
Test(b);
printf("%i, ",b[0]);
printf("%i, ",b[1]);
printf("%i ",b[2]);
return EXIT_SUCCESS;
}
Can somebody explain to me why only the second one works?
Best Regards,
Rob
When you pass an array to a function, it decays into a pointer to the first element. That's what the function sees. But then you take the function parameter vector and overwrite it with dynamically allocated memory. Then you don't have access to the array you passed in. Additionally, you have a memory leak because you didn't free the allocated memory.
In the case of the second function you don't modify vector, so when you dereference the pointer you're changing b in main.
Also, instead of this:
*(vector+i)
Use this:
vector[i]
It's much clearer to the reader what it means.
test doesn't need to call malloc(). When you use an array as a function argument, it passes a pointer to the array. So you can simply write into vector[i] and it will modify the caller's array.
void Test(int * vector){
int i;
for(i=0;i<3;i++){
*(vector+i)=i;
}
}

Pointer to pointer or global variables?

Below I have to examples of code that do the same thing and give the same output. In the first, I use pointer to pointer argument passing to eliminate the use of ans as a global. In the second, I madeans a global which eliminated the additional uses of * when dealing with pointer to pointer:
Example 1:
// pointer to pointer
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
unsigned char serial[] = {
0x1,0x2,0x3,0x4
};
void checkSerial(unsigned char* buf, unsigned char ** ans)
{
int i;
unsigned char *part;
part = 0;
i=2;
part = &buf[i];
*ans = (unsigned char*)malloc(2);
memset(*ans,0,2);
memcpy(*ans,part,2);
printf("0x%x\n",**ans);
++(*ans);
printf("0x%x\n",**ans);
}
int main(void)
{
unsigned char *ans, *buf;
while(1)
{
buf = malloc(4);
memset(buf,0,4);
memcpy(buf, serial, sizeof(serial));
checkSerial(buf, &ans);
--ans;
printf("the value is 0x%x\n", *ans);
free(buf);
free(ans);
sleep(3);
}
return 0;
}
Example 2:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
unsigned char serial[] = {
0x1,0x2,0x3,0x4
};
unsigned char ans[2];
void checkSerial(unsigned char* buf)
{
int i;
unsigned char *part;
part = 0;
i=2;
part = &buf[i];
int j;
for(j=0;j<2;j++)
{
ans[j] = part[j];
}
printf("0x%x\n",*ans);
++(*ans);
printf("0x%x\n",*ans);
}
int main(void)
{
unsigned char *buf;
while(1)
{
buf = malloc(4);
memset(buf,0,4);
memcpy(buf, serial, sizeof(serial));
checkSerial(buf);
printf("the value is 0x%x\n", *ans);
free(buf);
sleep(3);
}
return 0;
}
Which technique is preferred in C?
Avoid global variables when it is not necessary. Going with first example is preferable.
Global variables are easily accessible by every functions, they can be read or modified by any part of the program, making it difficult to remember or reason about every possible use.
Keep variables as close to the scope they are being used in as possible. This prevents unexpected values for your variables and potential naming issues.
I personally don't like defining global variable where there is ways to avoid it.
But some guys say that, the concept of pointer is very much confusing. I don't feel that though..
My advice, if you get confuse with pointers try to avoid it with defining global variable. Otherwise, use pointers... :)
TL;DR: Solutions 1 and 2 are both bad.
The way you wrote the example makes malloc useless since you know the size of ans and buf at compile-time, if those are really known at compile-time then , just don't use malloc at all, declare variables on the stack. In C, generally avoid dynamic memory allocation as much as possible and prefer to create buffers which can hold the maximum size a buffer can have in your application. That avoids this kind of problems in the first place. The way you wrote the example makes malloc useless since you know the size of ans and buf at compile-time. The only place where dynamic memory allocation can be useful is for buffers whose sizes are unknown at compile-time, but you can still avoid it (see below). If buf is an incoming message, and ans the answer to this message, the size of ans can be unknown at compile-time, at least if you use variable-length messages.
Your version 2 is not working and can not work! First you declared ans to be an array of size 1 and iterate over it until index 2(now you edited that). Second to declare the array ans as global you would need to know its size at compile-time, and then of course if you knew its size at compile-time you would just declare the array ans in the function checkSerial. Moreover, when you declare a variable which is used by several functions in C don't forget to declare it static, otherwise it can be accessed from all files in your project.
A solution avoiding dynamic allocation, notice you avoid the disadvantages of your 2 solutions: the pointer to pointer and the global variable, and moreover your program can not leak since you don't use dynamic allocation:
enum {MSG_MAX_SIZE = 256 };
typedef struct message {
uint8_t payload[MSG_MAX_SIZE];
size_t msg_size;
} message_t;
void checkSerial(const message_t *buf, message_t *ans)
{
//parse buf and determine size of answer
...
...
//fill answer payload
ans->msg_size = buf[42];
}
int main(void)
{
while (1) {
message_t buf;
getMsg(&buf);
message_t ans;
checkSerial(&buf, &ans);
}
}

How to return an array in c

I know this question has been asked before but cannot find it in the same manner as I will describe it here:
Its all about returning an one-dimensional array in c-language. In java its very easy:
double[] myFunction() {
double[] v = new double[10];
return v;
}
I know that the implementation in c is not the same. But as an array element can be considered as a pointer to the first element in that array I thought one could do the following implementation:
double (*myFunction()) {
double v[10];
return v;
}
This compiles fine in gcc but when I make a call of the function I get a compilation error.
SO my Question - how does one return a one-dimensional vector in c-language?
Thanks
sample code
#include <stdio.h>
#include <stdlib.h>
double *myFunction1(){
return malloc(10*sizeof(double));
}
double (*myFunction2())[10]{
double (*p)[10];
p = malloc(sizeof(double[10]));
return p;
}
typedef struct d10 {
double vec[10];
} D10;
D10 myFunction3(){//Make little sense
D10 v = {{0}};
v.vec[9]=1.25;
return v;
}
int main(){
double *v1 = myFunction1();
double (*v2)[10] = myFunction2();
D10 v3= myFunction3();
//do something
printf("%lf\n", v3.vec[9]);
v1[0] = 3.14;
(*v2)[0] = 3.14 * 2;
free(v1);
free(v2);
return 0;
}
Corrected:
You can't pass an array and you can't return an array you only pass an address to it or return a pointer to it first element:
double *someFunction()
{
double *output;
p = (double *)malloc(size*sizeof(double)); // size should be defined
//... do some process with the content pointed to by output
return output; // return the address pointed to by output
}
Or pass a pointer to it first element and do some process on the content pointed to.
void someFunction(double *output, int size)
{
//... do some process with the content pointed to by output
}
For one, declaring v in the function makes the array live only in that function. Once the function returns, that array is popped off the stack, and is likely to be modified after successive function calls.
The proper C solution is to use malloc to allocate an amount of space that you can use as an array, and return the pointer to that array.
double * myFunc(){
double * v = malloc(10*size of(double));
return v;
}
In Java, it was safe to return an array because the garbage collector could detect that the array was still in use, after it was popped off the stack.
how does one return a one-dimensional vector in c-language?
Technically speaking, one doesn't. C functions cannot return array types.
The main problem you are running into is that, in the C code, v only exists for the lifetime of the function; once the function exits, v no longer exists, so any pointer you return will not be valid.
For this to work, you'll have to do something similar to what the Java code is doing; you'll need to allocate the memory for the array from the heap (i.e., allocate it dynamically):
double *myfunction()
{
double *v = malloc( sizeof *v * 10 );
return v;
}
Note that C does not clean up after you, so you'll have to explicitly free that memory when you're done with it, such as:
int main( void )
{
double *arr = myfunction();
/**
* do stuff with arr
*/
free( arr );
return 0;
}

Resources