Related
With my programm I try to change the order of numbers in the int array. To the first function, I just passed both arrays and printed the array called arraytemp with the changed order. After that I printed in the main function the same array, just to see if the array was filled too. I havented used any pointers in the first function - how did the array got filled? Does the arrays adress get passed to functions anyway?
Then I wanted to pass arrays with the same content to the second function, but this time I used pointers. I have no clue, how to get the same result printed, because I get a stack smashing error. I am kinda comfused with '*' and '&'. So, how should I pass these arrays when using pointers?
#include <stdio.h>
void switchnum (int arraytemp[6], int array[], int laenge) {
printf("\n\nAfter (in function 1):\n");
for(int i = 0 ; i<laenge ; i++) {
arraytemp[i] = array[laenge-1-i];
printf("%d ", arraytemp[i]);
}
return 0;
}
void switchnum2 (int *arraytemp2[6], int array2[], int laenge2) {
printf("\nAfter (in function2):\n");
for(int j = 0 ; j<laenge2 ; j++) {
arraytemp2[j] = array2[laenge2-1-j];
printf("%d ", arraytemp2[j]);
}
return 0;
}
int main() {
int array[] = {4,8,1,3,0,9};
int arraytemp[6];
printf("Before (main):\n");
for(int i = 0 ; i<6 ; i++) {
printf("%d ", array[i]);
}
switchnum(arraytemp, array, 6);
printf("\nAfter (in main):\n");
for(int i = 0 ; i<6 ; i++) {
printf("%d ", arraytemp[i]);
}
int array2[] = {4,8,1,3,0,9};
int arraytemp2[6];
switchnum2(arraytemp2, array2, 6);
return 0;
}
The compiler adjusts a parameter having an array type to pointer to the array element type.
So this function declaration
void switchnum (int arraytemp[6], int array[], int laenge);
is equivalent to the following declaration
void switchnum (int arraytemp[], int array[], int laenge);
and the same way is equivalent to the following declaration
void switchnum (int *arraytemp, int *array, int laenge);
As for this function declaration
void switchnum2 (int *arraytemp2[6], int array2[], int laenge2);
then it is adjusted by the compiler to the declaration
void switchnum2 (int **arraytemp2, int *array2, int laenge2);
So the used argument expression and the function parameter have incompatible pointer types.
Pay attention to that in this call
switchnum(arraytemp, array, 6);
the both arrays are converted to pointers to their first elements of the type int *.
In fact this call is equivalent to
switchnum( &arraytemp[0], &array[0], 6);
How to pass pointer of arrays to functions
In this case you are trying to pass an array of pointers to a function and not a pointer of arrays:
void switchnum2(
int* arraytemp2[6], int array2[], int laenge2)
Maybe it helps to see the output of this example program, as it shows the output of many of your cases
Example
#include <stdio.h>
void test_arr(int*[6]);
int main(void)
{
int array[] = {4, 8, 1, 3, 0, 9};
int* pArr[6] = {0}; // 6 pointers to int
printf("original vector in main(): ");
for (int i = 0; i < 6; i += 1) printf("%d ", array[i]);
printf("\n");
for (int i = 0; i < 6; i++) pArr[i] = &array[i];
test_arr(pArr);
printf("\nIn main() &array[0] = %p\n", &array[0]);
return 0;
}
void test_arr(int* pInt[6])
{
printf("In test_array(): ");
for (int i = 0; i < 6; i += 1)
printf("%d ", *pInt[i]);
printf("\n");
int* myP = *pInt;
printf("*pInt\tpoints to value %d\n", *myP);
myP = pInt[0];
printf("pInt[0]\tpoints to value %d\n", *myP);
int x = *pInt[0];
printf("*pInt[0] = %d\n", x);
printf("\ntest_array() &pInt[0] = %X\n", pInt[0]);
return;
}
output
original vector in main(): 4 8 1 3 0 9
In test_array(): 4 8 1 3 0 9
*pInt points to value 4
pInt[0] points to value 4
*pInt[0] = 4
test_array() &pInt[0] = 197BFB00
In main() &array[0] = 000000CF197BFB00
Your program with some changes in the functions
I changed some lines in your code to get the expected result
#include <stdio.h>
void switch1(const int[],int[],const int);
void switch2(const int[],int*[],const int);
void show_array(const int[6],const char*);
int main(void)
{
int arr_out[] = {0,0,0,0,0,0};
show_array(arr_out, "arr_out in main()");
// call 1st function
printf("switch1() uses int[] as output\n");
switch1((int[6]){6, 5, 4, 3, 2, 1}, arr_out, 6);
show_array(arr_out, "arr_out using 6..1 array as input and 1st function");
// for 2nd function we need an array of pointers
int* pArr[6] = {0}; // 6 pointers to int
for (int i = 0; i < 6; i++) pArr[i] = &arr_out[i];
printf("switch2() uses int*[] as output\n");
switch2((int[6]){1, 2, 3, 4, 5, 6}, pArr, 6);
show_array(arr_out, "arr_out using 1..6 array as input and 2nd function");
return 0;
}
void switch1(const int in[], int out[], const int laenge)
{
for (int i = 0; i < laenge; i++)
out[i] = in[laenge - 1 - i];
}
void switch2(const int in[], int* out[], const int laenge)
{
for (int i = 0; i < laenge; i++)
*out[i] = in[laenge - 1 - i];
}
void show_array(const int array[6], const char* msg)
{
printf("%s:\t", msg);
for (int i = 0; i < 6; i++) printf("%d ", array[i]);
printf("\n");
}
output of the modified code
arr_out in main(): 0 0 0 0 0 0
switch1() uses int[] as output
arr_out using 6..1 array as input and 1st function: 1 2 3 4 5 6
switch2() uses int*[] as output
arr_out using 1..6 array as input and 2nd function: 6 5 4 3 2 1
about the changes
void show_array(const int array[6], const char* msg)
{
printf("%s:\t", msg);
for (int i = 0; i < 6; i++) printf("%d ", array[i]);
printf("\n");
}
This function is a helper to show the array contents and accepts a title. Very convenient here
the 2 functions has no output (printf() calls)
parameters are declared const so we can build the vector at the function call
I am using shorter names and changed the order of arguments to input and then output
void switch1(const int in[], int out[], const int laenge)
{
for (int i = 0; i < laenge; i++)
out[i] = in[laenge - 1 - i];
}
void switch2(const int in[], int* out[], const int laenge)
{
for (int i = 0; i < laenge; i++)
*out[i] = in[laenge - 1 - i];
}
Here you see the difference between the 2 functions: a single asterisk.
But in order of using the second function you need to build the vector of pointers as here
// call 1st function
printf("switch1() uses int[] as output\n");
switch1((int[6]){6, 5, 4, 3, 2, 1}, arr_out, 6);
show_array(arr_out, "arr_out using 6..1 array as input and 1st function");
// for 2nd function we need an array of pointers
int* pArr[6] = {0}; // 6 pointers to int
for (int i = 0; i < 6; i++) pArr[i] = &arr_out[i];
printf("switch2() uses int*[] as output\n");
switch2((int[6]){1, 2, 3, 4, 5, 6}, pArr, 6);
show_array(arr_out, "arr_out using 1..6 array as input and 2nd function");
This is what I have currently, and I have no idea what to do to make it run:
void avg_sum(double a[], int n, double *avg, double *sum) {
int i;
*sum = 0.0;
for (i = 0; i < n; i++)
*sum += a[i];
*avg = *sum / n;
}
int main () {
int array[5] = {1, 2, 3, 4, 5};
int avg = 3;
int sum = 2;
avg_sum(array, 5, avg, sum);
}
I tried manipulating the arguments for running the function, but I can't figure out how to make it work. It can be simple, I just have to write a program to test the avg_sum function. That portion must remain the same.
You want this:
int main () {
double array[5] = {1, 2, 3, 4, 5}; // use double
double avg = 3;
double sum = 2;
avg_sum(array, 5, &avg, &sum); // call with &
}
avg_sum operates on doubles, therefore you need to provide doubles.
parametrers 3 and 4 must be pointers to double, therefore you need to use the address operator &.
All this is covered in the first chapters of your beginner's C txt book.
For starters these initializations
int avg = 3;
int sum = 2;
does not make a sense.
At least it will be more meaningfully to initialize these variables by zero
int avg = 0;
int sum = 0;
The function avg_sum expects that the third and fourth arguments will be accepted by reference through pointers to them.
void avg_sum(double a[], int n, double *avg, double *sum) {
So the function must be called like
avg_sum(array, 5, &avg, &sum);
Also the function expects that the first, third and fourth arguments declared with the type specifier double but you are passing arguments declared with the type specifier int.
The function itself should be declared and defined the following way
void avg_sum( const int a[], size_t n, double *avg, int *sum )
{
*sum = 0;
for ( size_t i = 0; i < n; i++ )
{
*sum += a[i];
}
*avg = n == 0 ? 0.0 : *sum / n;
}
So within main the variables avg and sum have to be declared like
double avg = 0.0;
int sum = 0;
Also after the call of the function
avg_sum(array, 5, &avg, &sum);
it seems you should output the obtained values like for example
printf( "sum = %d, average = %.2f\n", sum, avg );
I made this program to find the sum of an array using pointer, but it crashes when I run it. Why is this happening and what did I do wrong?
int GetValue(int *p[], int size)
{
int i, sum = 0;
for(i = 0 ; i < size ; i++)
{
sum += *p[i];
}
return sum;
}
int main()
{
int Array[6] = { 20, 30, 40, 50, 60, 70 };
int Array_Sum;
Array_Sum = GetValue(&Array[6], 6);
printf("Array Sum= %d", Array_Sum);
return 0;
}
This ...
int Array[6] = { 20, 30, 40, 50, 60, 70 };
declares 'Array' as an array of 6 int. Note well that the declared name is 'Array', not 'Array[6]'. The latter expression, outside the context of a declaration, would designate the element at index 6 in that array if the array were long enough, but the array is not long enough, having only 6 elements, at indices 0 - 5.
If, again, the array were long enough, &Array[6] would evaluate to the address of the seventh element of Array (at index 6), but you presumably want to pass the address of the first element (at index 0). The expression &Array[0] would be one way to write that, but most people would instead simply write Array, which is completely equivalent. That is, you should call your function like so:
Array_Sum = GetValue(Array, 6);
You furthermore have a problem with your GetValue() function:
int GetValue(int *p[], int size) {
[...]
Parameter p is declared as a pointer to pointer to int. That is, the function signature is exactly equivalent to
int GetValue(int **p, int size) {
But what you're actually passing (and indeed what you want to pass) is an int *. You can write that either like this ...
int GetValue(int *p, int size) {
... or if you prefer, like this ...
int GetValue(int p[], int size) {
. Having done so, inside the function you should access the array elements as p[i], not *p[i].
Correction needed is here:
p[i] means *(p+i)
so,
*p[i] means **(p+i)
corrected function:
int GetValue(int *p, int size) //*p[] is for passing a 2D array ,pass 1D only as your need
{
int i, sum = 0;
for(i = 0 ; i < size ; i++)
{
sum += p[i]; //correction here that's why it crashes
}
return sum;
}
as p already is a pointer no need to derefence it.
live demo here http://ideone.com/kI1hXA
Thanks #JohnBollinger for pointing its 2D argument in getValuefunction in question.
I changed some things in your code
int GetValue(int *p, int size)
{
int i, sum = 0;
for(i = 0 ; i < size ; i++)
{
sum += p[i];
}
return sum;
}
int main()
{
int Array[6] = { 20, 30, 40, 50, 60, 70 };
int Array_Sum;
Array_Sum = GetValue(&Array[0], 6);
printf("Array Sum= %d", Array_Sum);
return 0;
}
The code is to be changed to -
int GetValue(int p[], int size)
{
int i, sum = 0;
for(i = 0 ; i < size ; i++)
{
sum += p[i];
}
return sum;
}
int main()
{
int Array[6] = { 20, 30, 40, 50, 60, 70 };
int Array_Sum;
Array_Sum = GetValue(Array, 6);
printf("Array Sum= %d", Array_Sum);
return 0;
}
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.
How can I include the elements of array X and Y in to array total in C language ?
can you please show with an example.
X = (float*) malloc(4);
Y = (float*) malloc(4);
total = (float*) malloc(8);
for (i = 0; i < 4; i++)
{
h_x[i] = 1;
h_y[i] = 2;
}
//How can I make 'total' have both the arrays x and y
//for example I would like the following to print out
// 1, 1, 1, 1, 2, 2, 2, 2
for (i = 0; i < 8; i++)
printf("%.1f, ", total[i]);
Your existing code is allocating the wrong amount of memory because it doesn't take sizeof(float) into account at all.
Other than that, you can append one array to the other with memcpy:
float x[4] = { 1, 1, 1, 1 };
float y[4] = { 2, 2, 2, 2 };
float* total = malloc(8 * sizeof(float)); // array to hold the result
memcpy(total, x, 4 * sizeof(float)); // copy 4 floats from x to total[0]...total[3]
memcpy(total + 4, y, 4 * sizeof(float)); // copy 4 floats from y to total[4]...total[7]
for (i = 0; i < 4; i++)
{
total[i] =h_x[i] = 1;
total[i+4]=h_y[i] = 2;
}
A way to concatenate two C arrays when you know their size.
#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;
}
I thought I'd add this because I've found it necessary in the past to append values to a C array (like NSMutableArray in Objective-C). This code manages a C float array and appends values to it:
static float *arr;
static int length;
void appendFloat(float);
int main(int argc, const char * argv[]) {
float val = 0.1f;
appendFloat(val);
return 0;
}
void appendFloat(float val) {
/*
* How to manage a mutable C float array
*/
// Create temp array
float *temp = malloc(sizeof(float) * length + 1);
if (length > 0 && arr != NULL) {
// Copy value of arr into temp if arr has values
memccpy(temp, arr, length, sizeof(float));
// Free origional arr
free(arr);
}
// Length += 1
length++;
// Append the value
temp[length] = val;
// Set value of temp to arr
arr = temp;
}
may be this is simple.
#include <stdio.h>
int main()
{
int i,j,k,n,m,total,a[30],b[30],c[60];
//getting array a
printf("enter size of array A:");
scanf("%d",&n);
printf("enter %d elements \n",n);
for(i=0;i<n;++i)
{scanf("%d",&a[i]);}
//getting aaray b
printf("enter size of array b:");
scanf("%d",&m);
printf("enter %d elements \n",m);
for(j=0;j<m;++j)
{scanf("%d",&b[j]);}
total=m+n;
i=0,j=0;
//concating starts
for(i=0;i<n;++i)
{
c[i]=a[i];
}
for(j=0;j<m;++j,++n)
{
c[n]=b[j];
}
printf("printing c\n");
for(k=0;k<total;++k)
{printf("%d\n",c[k]);}
}
Here a solution to concatenate two or more statically-allocated arrays. Statically-allocated arrays are array whose length is defined at compile time. The sizeof operator returns the size (in bytes) of these arrays:
char Static[16]; // A statically allocated array
int n = sizeof(Static_array); // n1 == 16
We can use the operator sizeof to build a set of macros that will concatenate two or more arrays, and possibly returns the total array length.
Our macros:
#include <string.h>
#define cat(z, a) *((uint8_t *)memcpy(&(z), &(a), sizeof(a)) + sizeof(a))
#define cat1(z, a) cat((z),(a))
#define cat2(z, a, b) cat1(cat((z),(a)),b)
#define cat3(z, a, b...) cat2(cat((z),(a)),b)
#define cat4(z, a, b...) cat3(cat((z),(a)),b)
#define cat5(z, a, b...) cat4(cat((z),(a)),b)
// ... add more as necessary
#define catn(n, z, a ...) (&cat ## n((z), a) - (uint8_t *)&(z)) // Returns total length
An example of use:
char One[1] = { 0x11 };
char Two[2] = { 0x22, 0x22 };
char Three[3] = { 0x33, 0x33, 0x33 };
char Four[4] = { 0x44, 0x44, 0x44, 0x44 };
char All[10];
unsigned nAll = catn(4, All, One, Two, Three, Four);
However, thanks to the way we defined our macros, we can concatenate any type of objects as long as sizeof returns their size. For instance:
char One = 0x11; // A byte
char Two[2] = { 0x22, 0x22 }; // An array of two byte
char Three[] = "33"; // A string ! 3rd byte = '\x00'
struct {
char a[2];
short b;
} Four = { .a = { 0x44, 0x44}, .b = 0x4444 }; // A structure
void * Eight = &One; // A 64-bit pointer
char All[18];
unsigned nAll = catn(5, All, One, Two, Three, Four, Eight);
Using constant literals, one can also these macros to concatenate constants, results from functions, or even constant arrays:
// Here we concatenate a constant, a function result, and a constant array
cat2(All,(char){0x11},(unsigned){some_fct()},((uint8_t[4]){1,2,3,4}));
i like the answer from jon. In my case i had to use a static solution.
So if you are forced to not use dynamic memory allocation:
int arr1[5] = {11,2,33,45,5};
int arr2[3] = {16,73,80};
int final_arr[8];
memcpy(final_arr, arr1, 5 * sizeof(int));
memcpy(&final_arr[5], arr2, 3 * sizeof(int));
for(int i=0; i<(sizeof(final_arr)/sizeof(final_arr[0]));i++){
printf("final_arr: %i\n", final_arr[i]);
}
Why not use simple logic like this?
#include<stdio.h>
#define N 5
#define M (N * 2)
int main()
{
int a[N], b[N], c[M], i, index = 0;
printf("Enter %d integer numbers, for first array\n", N);
for(i = 0; i < N; i++)
scanf("%d", &a[i]);
printf("Enter %d integer numbers, for second array\n", N);
for(i = 0; i < N; i++)
scanf("%d", &b[i]);
printf("\nMerging a[%d] and b[%d] to form c[%d] ..\n", N, N, M);
for(i = 0; i < N; i++)
c[index++] = a[i];
for(i = 0; i < N; i++)
c[index++] = b[i];
printf("\nElements of c[%d] is ..\n", M);
for(i = 0; i < M; i++)
printf("%d\n", c[i]);
return 0;
}
Resultant array size must be equal to the size of array a and b.
Source: C Program To Concatenate Two Arrays