Reference data from a array to another array in C - c

I want to reference new array to address from another array in C code like this:
int main()
{
int a[6] = {1,2,3,4,5,6};
int b[6];
unsigned long long int *c = &a[5];
unsigned long long int *d = &b[5];
int size = 6;
for(;size>0;size--,c--,d--){
*d = *c;
}
return 0;
}
but my code didn't work. can you tell me whats wrong in this code?

The data type of your pointer doesn’t match the data type of the array

These declarations
unsigned long long int *c = &a[5];
unsigned long long int *d = &b[5];
are incorrect because the declared objects have the type unsigned long long int * but are initialized by expressions of the type int *. Thus dereferencing the declared pointers you can get unexpected results.
If you want to use the pointer arithmetic in a for loop for example to copy the first array into the second array in the reverse order then the program can look the following way.
#include <stdio.h>
int main(void)
{
enum { N = 6 };
int a[N] = { 1, 2, 3, 4, 5, 6 };
int b[N];
for ( int * c = a + N, *d = b; c != a; )
{
*d++ = *--c;
}
for ( const int *d = b; d != b + N; ++d )
{
printf( "%d ", *d );
}
putchar ( '\n' );
return 0;
}
The program output is
6 5 4 3 2 1

Related

Subtracting a sequence of numbers using for loop in C Programming

int myfunc(int a, int b)
{
int result = a;
for(int index = a - 1; index >= b; index--)
{
result -= index;
}
return result;
}
How to make this function subtract numbers from the smallest number to the greatest number depending on the values of a and b that I choose ? (e.g. if a = 5 and b = 8 , then the program would type 5-6-7-8 = -16)
You're going the "wrong direction". Look at what you want to do:
5-6-7-8 = -16
^ ^ ^ ^
a | | |
a+1| |
a+2|
a+3
So start at a+1 and count up to b
int result = a;
for(int index = a + 1; index <= b; index++)
{
result -= index;
}
// result = -16 for a=5, b=8
Demo
For starters the variable index is redundant.
To avoid an overflow (at least in most cases) the variable result should have the type long long int instead of int. For example if you will run your function like
myfunc( INT_MIN , INT_MIN + 3 );
(provided that you have included the header <limits.h>) when if the type of the variable result is int then the function will return the value -6 (actually the behavior is undefined in this case) while if the variable result has the type long long int then you will get the correct result 4294967290.
The function can look the following way
long long int myfunc( int a, int b )
{
if ( b < a )
{
int tmp = b;
b = a;
a = tmp;
}
long long int result = a;
while ( a < b )
{
result -= ++a;
}
return result;
}
Here is a demonstrative program.
#include <stdio.h>
long long int myfunc( int a, int b )
{
if ( b < a )
{
int tmp = b;
b = a;
a = tmp;
}
long long int result = a;
while ( a < b )
{
result -= ++a;
}
return result;
}
int main(void)
{
printf( "%lld\n", myfunc( 8, 5 ) );
return 0;
}
The program output is
-16

Why does const not work even if the variable is not changed?

I'm trying to protect the -a- array of the my_sum_array function from the changes. In the function block I do not make any changes to -a-, but I have a warning (warning: assignment to 'int *' from 'const int *' discards the qualifiers [-Wincompatible-pointer-types-discards-qualifiers]). I know I could remove const to make the program work, but I would like to understand if something is missing from me.
#include <stdio.h>
#define MAX 5
int my_sum_array(const int a[], int n);
int main(void) {
int values[5] = {4, 7, 1, 7, 8};
printf("The sum in my_sum_array is :%d\n", my_sum_array(values, MAX));
return 0;
}
int my_sum_array(const int a[], int n) {
int *p, sum = 0;
for (p = a; p < a + n; p++)
sum += *p;
return sum;
}
The warning is caused by the assignment p = a in the for loop. The variable is defined as int *p, a pointer to non-const int. The warning is correct, "assignment to int * from const int * discards the qualifiers". It's as though you've casted away the constness of the a pointer parameter.
I'd change your function to:
int my_sum_array(const int a[], int n) {
int sum = 0;
for (const int *p = a; p < a + n; p++)
sum += *p;
return sum;
}
This defines p as a pointer-to-const, just like a, and also limits its lifetime to the for loop.
Make your p pointer as:
int const * p;
i.e.
here, p is a pointer to a const integer
Change type of p to:
const int *p;
So now you end up with:
const int * p;
int sum = 0;

Generic swap function using pointer to char in C

I don't understand so well how this code works:
#include <stdio.h>
void gswap(void* ptra, void* ptrb, int size)
{
char temp;
char *pa = (char*)ptra;
char *pb = (char*)ptrb;
for (int i = 0 ; i < size ; i++) {
temp = pa[i];
pa[i] = pb[i];
pb[i] = temp;
}
}
int main()
{
int a=1, b=5;
gswap(&a, &b, sizeof(int));
printf("%d , %d", a, b)
}
What I understand is that char has 1 byte(size) in memory and we are using pointers to swap each byte of the int value(4 bytes).
But in the end, how it is possible to dereference a char pointer to int value?
Let's try and figure this out, step by step, with code comments
#include <stdio.h>
//gswap() takes two pointers, prta and ptrb, and the size of the data they point to
void gswap(void* ptra, void* ptrb, int size)
{
// temp will be our temporary variable for exchanging the values
char temp;
// We reinterpret the pointers as char* (byte) pointers
char *pa = (char*)ptra;
char *pb = (char*)ptrb;
// We loop over each byte of the type/structure ptra/b point too, i.e. we loop over size
for (int i = 0 ; i < size ; i++) {
temp = pa[i]; //store a in temp
pa[i] = pb[i]; // replace a with b
pb[i] = temp; // replace b with temp = old(a)
}
}
int main()
{
// Two integers
int a=1, b=5;
// Swap them
gswap(&a, &b, sizeof(int));
// See they've been swapped!
printf("%d , %d", a, b);
}
So, basically, it works by going over any given datatype, reinterpreting as bytes, and swapping the bytes.

I am getting Segmentation fault: 11

I am getting error on the line where I put "<<--" (line 9) sign. it didn't had any compiling error , but while giving input it says "Segmentation fault: 11". I don't know what went wrong.
input:
3 3
1 1 1
2 2 2
3 1 5
The code:
#include <stdio.h>
#include <stdlib.h>
int comp (const void * x, const void * y)
{
int *a = *(int **)x;
int *b = *(int **)y;
//getting error here
if (a[0] == b[0]) // <<-- here
{
if (a[2] == b[2])
{
return -(a[1] - b[1]);
}
else
{
return a[2] - b[2];
}
}
else
{
return a[0] - b[0];
}
}
int main()
{
int n;
long long d;
scanf("%d %lld", &n, &d);
int t[n][3];
for (int i = 0; i < n; i++)
{
scanf ("%d %d %d", &t[i][0], &t[i][1], &t[i][2]);
}
printf("%lu\n", sizeof(t[0]));
qsort(t, n, sizeof(t[0]), comp);
for (int i = 0; i < n; ++i)
{
printf("%d-%d-%d\n", t[i][0], t[i][1], t[i][2]);
}
}
Can anyone help me with this?
Your
int t[n][3];
array is actually an 1D array consisting of n 1D arrays of type int [3]. These int [3] objects is what you are trying to sort by your
qsort(t, n, sizeof(t[0]), comp)
call.
So, in order to properly compare these objects you have to interpret the parameters of your comparison callback as pointers to int [3] objects. Meanwhile, your current implementation of comp is written as if the parameters are pointing to int * objects, which is incorrect. int [3] and int * are two very different things.
This is how you can do it
int comp (const void * x, const void * y)
{
int (*a)[3] = x;
int (*b)[3] = y;
// And now compare the arrays by accessing them as `(*a)[1]`,
// `(*b)[2]` and so on
}
Alternatively, you can write the comp prologue code as
int comp (const void * x, const void * y)
{
const int *a = *(int (*)[3]) x;
const int *b = *(int (*)[3]) y;
// And now compare the arrays by accessing them as `a[1]`,
// `b[2]` and so on, i.e. keep the rest of your code unchanged
}
This assumes that the rest of your comparison logic is correct. Note though that comparing int values by subtracting them from each other is risky, since it can overflow.

Concatenating 2 arrays in C [duplicate]

This question already has answers here:
How to access a local variable from a different function using pointers?
(10 answers)
Closed 6 years ago.
I'm trying to create a function that concatenates 2 arrays and then returns the sum array back.
I've been using the following code:
#include "stdio.h";
struct array {
int length;
int *array;
};
struct array add(struct array a, struct array b) {
int length = a.length + b.length;
int sum[length];
for (int i = 0; i < length; ++i) {
if (i < a.length) {
sum[i] = a.array[i];
} else {
sum[i] = b.array[i - a.length];
}
}
struct array c;
c.length = length;
c.array = sum;
return c;
}
int main() {
int a[] = {1, 2, 3};
struct array s1;
s1.array = a;
s1.length = sizeof(a) / sizeof(a[0]);
int b[] = {4, 5, 6};
struct array s2;
s2.array = b;
s2.length = sizeof(b) / sizeof(b[0]);
struct array sum = add(s1, s2);
for (int i = 0; i < sum.length; ++i) {
printf("%d\n", sum.array[i]);
}
return 0;
}
The output is:
1,
17,
6356568,
1959414740,
1,
1959661600
What am I doing wrong?
These three lines are very problematic:
int sum[length];
...
c.array = sum;
return c;
In the first you declare the local variable sum. In the second you make c.array point to the local variable. And in the third line you return the pointer while the local variable goes out of scope.
Since the local variable goes out of scope it no longer exists, and the pointer to it is no longer valid. Using the pointer will lead to undefined behavior.
To solve this you need to allocate memory dynamically with e.g. malloc.
sum is a local variable to the add function. When you set c.array = sum;, then the pointer c.array points to this local variable.
After the function returns, local variables are destroyed. So this pointer is now a dangling pointer. But in main you then read through this pointer.
To fix this you'll need to make a fundamental change to the design of your program. For example, use dynamic allocation in all cases for a struct array.
Arrays in C simply are a contiguous area of memory, with a pointer to their start*. So merging them involves:
Find the length of the arrays A and B, (you will probably need to know the number of elements and the sizeof each element)
Allocating (malloc) a new array C that is the size of A + B.
Copy (memcpy) the memory from A to C,
Copy the memory from B to C + the length of A (see 1).
You might want also to de-allocate (free) the memory of A and B.
Example code snippet:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define ARRAY_CONCAT(TYPE, A, An, B, Bn) \
(TYPE *)array_concat((const void *)(A), (An), (const void *)(B), (Bn), sizeof(TYPE));
void *array_concat(const void *a, size_t an,const void *b, size_t bn, size_t s)
{
char *p = malloc(s * (an + bn));
memcpy(p, a, an*s);
memcpy(p + an*s, b, bn*s);
return p;
}
// testing
const int a[] = { 1, 1, 1, 1 };
const int b[] = { 2, 2, 2, 2 };
int main(void)
{
unsigned int i;
int *total = ARRAY_CONCAT(int, a, 4, b, 4);
for(i = 0; i < 8; i++)
printf("%d\n", total[i]);
free(total);
return EXIT_SUCCCESS;
}
Try this - corrected add function:
#include <stdlib.h>
struct array add(struct array a, struct array b) {
int length = a.length + b.length;
int * sum = (int*)calloc(length, sizeof(int));
for (int i = 0; i < length; ++i) {
if (i < a.length) {
sum[i] = a.array[i];
}
else {
sum[i] = b.array[i - a.length];
}
}
struct array c;
c.length = length;
c.array = sum;
return c;
}
stdlib is required to use calloc function.
That function allocate memory for length values of int type. To be sure that memory is allocated successfully, it is recommended to check value of pointer sum after allocation, e.g.:
int * sum = (int*)calloc(length, sizeof(int));
if( sum != NULL )
{
// use memory and return result
}
else
{
// do not use pointer (report about error and stop operation)
}
As Joachim mentioned, you are returning a local variable int sum[length]; This is a bad idea. The variable sum is returned to the stack after the function exits and can be overwritten by other stack variables.
One of the ways around that is to not declare an array inside the sum function in the first place. The sum_str is declared in main. You can pass the pointer to this structure to the sum function.
The updated code is below.
#include <stdio.h>
struct array {
int length;
int *array;
};
void add(struct array a, struct array b, struct array *sum_str) {
sum_str->length = a.length + b.length;
for (int i = 0; i < sum_str->length; ++i) {
if (i < a.length) {
sum_str->array[i] = a.array[i];
} else {
sum_str->array[i] = b.array[i - a.length];
}
}
}
int main() {
int a[] = {1, 2, 3};
struct array s1;
s1.array = a;
s1.length = sizeof(a) / sizeof(a[0]);
int b[] = {4, 5, 6};
struct array s2;
s2.array = b;
s2.length = sizeof(b) / sizeof(b[0]);
struct array sum_str;
int sum_a[6];
sum_str.array = sum_a;
add(s1, s2, &sum_str);
for (int i = 0; i < sum_str.length; ++i) {
printf("%d\n", sum_str.array[i]);
}
return 0;
}
Another way is to use dynamic memory allocation as described by other answers.

Resources