Why array values are different from assigned values C program - c

I wrote a small code to that takes an array of 10 values, passes the array to a function which doubles each value. The array prints expected values (double) within the function. Back in the main function, the output printed has garbage values for index 1, 2 and 3 in the for loop meant to print all values. Why are these values altered? The address is the same in both main and called functions.
StructA doubleArray(int* alist, int b) {
StructA doubled;
int temp[b];
for(int i=0; i < b; i++){
temp[i] = 2 * alist[i];
}
doubled.a = temp;
doubled.b = b;
return doubled;
}
int main() {
int arange[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int len = 10;
StructA hasDoubledValues = doubleArray(arange, len);
printf("\nvalues in main :");
for(int k = 0; k < hasDoubledValues.b; k++){
printf(" %d \n", hasDoubledValues.a[k]);
}
return 0;
}
its printing values as : 0 0 -14334592 32507 8 10 12 14 16 18
I expected the values to be : 0 2 4 6 8 10 12 14 16 18

int temp[b]; is local to the function.
Once you return from the function, lifetime of that memory ceases and accessing it would yield undefined behaviour.

Related

During insertion of values to array, the values are correct. But after that, I get different values

I created a function which should return an array of indexes of some specific number.
The function attributes are: size of array , array, number and a pointer.
In the example below I get different values. There are two places where I check the values:
1) After the Insertion: Which looks correct
2) during Iteration over the returned array: Which returns different values, including addresses(why?)
These are the returned values:
During insertion:
3
11
17
20
21
23
6
Pointed array size : 6
During iteration:
3
11
17
21
2334102057621532978
3617293411120723765
int main()
{
size_t sizeToBeReturned;
int arrayOfInt[] = {12, 15, 2, 8, 13, 3, 14, 1, 13, 6, 0, 8, 14, 15, 14, 14, 2, 8, 0, 15, 8, 8, 9, 8, 0, 14};
size_t size = sizeof(arrayOfInt) / sizeof(int);
size_t *returnedArray = find_all(size, arrayOfInt, 8, &sizeToBeReturned);
for (int i = 0; i < sizeToBeReturned; i++) {
printf("%ld\n", returnedArray[i]);
//when I iterate the returned array, the values comes massed up
}
return 0;
}
size_t *find_all(size_t a, const int array[a], int number, size_t * z)
{
//printf("Array size: %zu\n", a);
size_t *toReturnArray = NULL;
size_t sizeOfArray = 0;
for (size_t i = 0; i < a; i++) {
if (array[i] == number) {
if (toReturnArray == NULL) {
toReturnArray = (size_t *) malloc(sizeof(int));
} else {
toReturnArray = realloc(toReturnArray, (sizeOfArray) * sizeof(int));
}
toReturnArray[sizeOfArray] = i;
printf("%ld\n", toReturnArray[sizeOfArray]);
//Here I can see the correct value
sizeOfArray++;
}
}
printf("%ld\n", sizeOfArray);
*z = sizeOfArray;
return toReturnArray;
}
You allocate as a dynamic array of int but you consider it
as a dynamic array of size_t (larger) while reading/writing.
toReturnArray = (size_t *) malloc(sizeof(size_t)); // not sizeof(int)
toReturnArray = realloc(toReturnArray, (sizeOfArray+1) * sizeof(size_t)); // not sizeof(int)
If on your system, for example, sizeof(int) is 4 and sizeof(size_t)
is 8, then the allocated memory is half the necessary size.
And something else I didn't see (thanks M Oehm) is the missing +1 in realloc().
By the way, realloc() accepts a null pointer (then behaves like
malloc()) so the test is not necessary: just use the line with realloc().

C, Why the function doesn't accept the 2d-array from txt file as an argument?

This is my C code and and .txt file. I want to use 2d-array from .txt file as a function argument. However, when I run this code, program gives error at the call function lines such:
[Error] cannot convert 'int (*)[C]' to 'int (*)[3]' for argument '1' to 'int rec_ped(int (*)[3], int)'.
Other words, my function rec_ped cannot accept the 2d-array from .txt file.
Could you help me about this?
#include <stdio.h>
int rec_ped(int k[18][3], int idx) {
int sire, dam;
sire = k[idx - 1][1];
dam = k[idx - 1][2];
printf("%d ", sire);
if (sire != 0)
rec_ped(k, sire);
if (dam != 0)
rec_ped(k, dam);
}
int main() {
int R = 18;
int C = 3;
int A[R][C];
FILE *fp;
int i, j;
fp = fopen("t.txt", "r");
for (i = 0; i < R; i++) {
for (j = 0; j < C; j++) {
fscanf(fp, "%d", &A[i][j]);
}
}
for (i = 0; i < R; i++) {
for (j = 0; j < C; j++) {
A[i][j];
rec_ped(A, 18); // <--- there is error!!!
}
}
return 0;
}
my file is a.txt as below;
1 0 0
2 0 0
3 0 0
4 0 0
5 0 0
6 1 3
7 1 5
8 0 2
9 4 6
10 0 0
11 1 0
12 4 10
13 7 11
14 1 6
15 13 0
16 1 15
17 4 14
18 16 17
When an array decays to a pointer, it only applies to the outermost array dimension. It does not apply to inner dimensions. So int (*)[3] and int (*)[C] are not the same, even though C happens to be 3 at the time the function is called. A fixed size array and a variable length array can't be considered the same in this situation.
What you can do however is pass the dimensions of an array as parameters:
int rec_ped(int rows, int cols, int k[rows][cols], int idx) {
Then you can call it like this:
rec_ped(R, C, A, 18);
Make C a constant (#define C 3)!
Problem is: Without C being constant, but a variable, it could have been modified before declaring the array, so the latter actually is a VLA. The function, in contrast, expects a fixed size array, so types don't match.
Be aware you don't have to make R constant:
int rec_ped(int k[18][3], int idx);
is equivalent to
int rec_ped(int k[][3], int idx);
which is equivalent to
int rec_ped(int (*k)[3], int idx);
i. e. the function actually accepts a pointer to an array of length 3 just like void f(int*); accepts a pointer to int. In both cases, the pointer could reference the first element of an array (array of array or array of int respectively) or just a single element...

incompatible pointer types passing int[5][5] to parameter of type int**

why this error(picture 1) happened when I want to input a 2d array to a function?
#include <stdio.h>
#include <stdlib.h>
void pr(int** a){
printf("%d", a[0][0]);
}
int main(){
int a[5][5]={{1,4,7,11,15},{2,5,8,12,19},{3,6,9,16,22},{10,13,14,17,24},{18,21,23,26,30}};
pr(a);
}
The core problem is that arrays and pointers are not the same (albeit they are closely related), and a 2D array is not an array of pointers.
This code shows three ways to fix up the problem. The array a0 is your array renamed and reformatted; the array a is an array of pointers, and each pointer is a pointer to an array of 5 int via a 'compound literal', a feature added to C99. I've upgraded the printing function to print all 25 elements of the array that is passed to it — and created two new printing functions with different interfaces that also print the entire array passed to them. I assume the array is square; a rectangular (non-square) matrix can be readily handled, especially by a variant on pr1() such as pr2(int n, int m, int a[n][m]) — which is almost identical to pr1() but needs a single adjustment internally to test j against m instead of n.
#include <stdio.h>
static void pr0(int a[][5]);
static void pr1(int n, int a[n][n]);
static void pr(int **a)
{
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
printf("%3d", a[i][j]);
putchar('\n');
}
putchar('\n');
}
int main(void)
{
int a0[5][5] =
{
{ 1, 4, 7, 11, 15 },
{ 2, 5, 8, 12, 19 },
{ 3, 6, 9, 16, 22 },
{ 10, 13, 14, 17, 24 },
{ 18, 21, 23, 26, 30 },
};
int *a[] =
{
(int[]){ 1, 4, 7, 11, 15 },
(int[]){ 2, 5, 8, 12, 19 },
(int[]){ 3, 6, 9, 16, 22 },
(int[]){ 10, 13, 14, 17, 24 },
(int[]){ 18, 21, 23, 26, 30 },
};
pr(a);
pr0(a0);
pr1(5, a0);
return 0;
}
static void pr0(int a[][5])
{
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
printf("%3d", a[i][j]);
putchar('\n');
}
putchar('\n');
}
static void pr1(int n, int a[n][n])
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
printf("%3d", a[i][j]);
putchar('\n');
}
putchar('\n');
}
The sample output is wonderfully uniform:
1 4 7 11 15
2 5 8 12 19
3 6 9 16 22
10 13 14 17 24
18 21 23 26 30
1 4 7 11 15
2 5 8 12 19
3 6 9 16 22
10 13 14 17 24
18 21 23 26 30
1 4 7 11 15
2 5 8 12 19
3 6 9 16 22
10 13 14 17 24
18 21 23 26 30
The three blocks are the same. Given a choice, I'd use the technique in pr1(), using VLAs (variable length arrays) in the interface. If you must stick with the int ** argument, you must stick with the array a, or something quite similar. There are certainly other ways to create that. For example:
int *a[] = { a0[0], a0[1], a0[2], a0[3], a0[4] };
Arrays and pointers can not be used interchangeably in all possible use cases, and you just happened to stumble into one of them. At times, an int array can be implicitly converted into a pointer, and at times it, well, shouldn't be.
In your case, implicitly (or explicitly) converting a to an (int **) would not work, simply because a points to the first element in your 2d array when considered as a pointer. Converting a to an int ** would make pr lose the information on a being an array. Consequently, handling it as a typical (int **) in pr and trying to dereference it twice would cause the first element in a (a[0][0] = 1) to be handled as an address and the value in that address would be looked up, which I believe is not the desired behavior of pr().
Ideally, you should declare pr in a way that takes a 2D array as a parameter, not an int **. A declaration of pr with the mentioned fix is given below.
void pr(int a[][5]){
printf("%d", a[0][0]);
}
Now, you mention in the comments to your question that the definition of pr can not be modified. In order not to modify pr(), you would have to change the data structure you have in main to something similar to the one given below.
int main(){
int a0[5]={1,4,7,11,15};
int a1[5]={2,5,8,12,19};
int a2[5]={3,6,9,16,22};
int a3[5]={10,13,14,17,24};
int a4[5]={18,21,23,26,30};
int *a[5] = {a0, a1, a2, a3, a4};
pr(a);
}
Note that the sample above is not the most syntactically concise way to achieve your goal. Also, check here to see this usage at work.

getting unexpected values in my simple program in C

when I am compiling this small program I am getting different values as output, instead of getting numbers from 0 to 5. And the size of array is always 8. The different values I am getting are:
-981774704
32767
0
0
4195728
0
Any tips would be really valuable. Thank you
#include <stdio.h>
int main() {
int array[10];
int i;
for (i = 0; i < 6; i++) {
printf("%d\n", array[i]);
}
int z = sizeof(&array);
printf("\n Size of array is %d", z);
return 0;
}
You aren't assigning any values to the array, so you're getting the uninitialized values.
You need to do something like array[0] = 5; //or some value etc.
If you want an array of size 8, with the numbers indexing the array stored in it, so {0, 1, 2, 3, 4, 5, 6, 7}, you could do something like:
int array[8];
for(int i = 0; i < 8; ++i)
{
array[i] = i;
}
the elements of the array are uninitialized therefore it's printing garbage value...first initialize the elements with values...you can do this...
#include<stdio.h>
int main()
{
int array[10] ;
int i;
for (i = 0; i < 6; i++)
{
array[i]=i;
printf("%d\n", array[i]);
}
int z = sizeof(&array);
printf("\n Size of array is %d", z);
return 0;
}
if you want the array to be initialized automatically then declare the array globally...
if you want to get the size of the whole array remove &
sizeof(array);
C will not initialize your array to any default value. When you create the array it will be full of garbage values (nothing relevant or defined). Always initialize your data using memset or something equivalnet.
So if you are expecting a value of 0 on a new array then initialize it like this:
memset(array, 0, sizeof(array));
you have to initialize your array first, memory may not be filled with 0 by default

Arguments and returning array in C

I am new to C and I am learning from "Programming in C" by Stephen G. Cochan. I have been given next exercise:
12.A matrix M with i rows, j columns can be transposed into a matrix N having j rows
and i columns by simply setting the value of N a,b equal to the value of M b,a for all
relevant values of a and b.
a) Write a function transposeMatrix that takes as an argument a 4 x 5 matrix
and a 5 x 4 matrix. Have the function transpose the 4 x 5 matrix and store
the results in the 5 x 4 matrix. Also write a main routine to test the function.
I have done something wrong with the arguments.
The errors I'm getting are:
warning: return makes integer from pointer without a cast [enabled by default]
passing argument 1 of ‘transposeMatrix’ makes pointer from integer without a cast [enabled by default]
expected ‘int (*)[5]’ but argument is of type ‘int’ (It seems to me like this can be ignored)
etc..all about arguments..
I know code is not perfect but i think it should work if array was returned correctly and arguments were fixed..but I can't find a way to fix it..
// Program to transpose M matrix to N matrix
#include <stdio.h>
int transposeMatrix(int matrixM[][5], int matrixN[][4]) {
int i, j;
i = 0;
j = 0;
for (i = 0; i < 4; i++) {
for (j = 0; j < 5; j++) {
matrixN[j][i] = matrixM[i][j];
}
}
return matrixN;
}
int main(void) {
int i, j;
int matrixM[4][5] = {{12, 25, 47, 87, 54},
{16, 89, 78, 63, 58},
{45, 21, 47, 62, 82},
{14, 56, 47, 41, 98}};
int matrixN[5][4];
transposeMatrix(matrixM[4][5], matrixN[5][4]);
i = 0;
j = 0;
for (j = 0; j < 5; j++) {
for (i = 0; i < 4; i++) {
printf("%i ", matrixN[j][i]);
}
printf("\n");
}
return 0;
}
There are two ways a function can pass data back to the caller:
Returning a value, and
Changing a data structure a pointer to which is passed to the function as an argument
The first way involves copying, and is inefficient for larger values. The second way is preferred when a large value needs to be returned without copying, or when you need to return multiple results.
Another problem is passing the arrays: your call should pass array names without indexes, like this:
transposeMatrix(matrixM,matrixN);
Your code is using the second strategy. However, it does not need to return anything else. Therefore, the proper return type for your function should be void, not int. Change the return type, and remove the return statement to fix this issue.
Demo on ideone.
Actually the code linked above doesn't really work, it's just printing a transposed matrix by switching rows with columns in the printf() call, it does not truly transpose the matrix as the exercise requires (you can avoid calling transposeMatrix at all and the result is the same). Pay attention to how the exercise is worded, you should use a function and store the results in a new matrix. Also, at this point in the book we're not supposed to use pointers (yet).
This is how I did it:
/*
A matrix M with i rows, j columns can be transposed into a matrix N having j rows and i columns
by simply setting the value of Na,b equal to the value of Mb,a for all relevant values of a and b.
Write a function transposeMatrix() that takes as an argument a 4 × 5 matrix and a 5 × 4
matrix. Have the function transpose the 4 × 5 matrix and store the results in the 5 × 4 matrix. Also
write a main() routine to test the function.
*/
#include <stdio.h>
void transposeMatrix(int matrix45[4][5], int matrix54[5][4])
{
int x, y;
for (x = 0; x < 4; x++)
for (y = 0; y < 5; y++)
matrix54[y][x] = matrix45[x][y];
}
int main(void)
{
int x, y;
int myMatrix[4][5] = { {0, 1, 2, 3, 4},
{5, 6, 7, 8, 9},
{10, 11, 12, 13, 14},
{15, 16, 17, 18, 19} };
int myTransposedMatrix[5][4];
printf("Original Matrix: \n\n");
for (x = 0; x < 4; x++)
{
for (y = 0; y < 5; y++)
{
printf("%3i", myMatrix[x][y]);
}
printf("\n");
}
transposeMatrix(myMatrix, myTransposedMatrix);
printf("\nTransposed Matrix: \n\n");
for (x = 0; x < 5; x++)
{
for (y = 0; y < 4; y++)
{
printf("%3i", myTransposedMatrix[x][y]);
}
printf("\n");
}
return 0;
}

Resources