Print array that was set in another function with pointers - c

As you can see in the code below I tried to print an array that I created in a different function. The output was totally different numbers compares to what I expected: numbers between 0 - 20 were set but I got some negative values.
So my question is why is this happening? And how to fix it if it even possible?
#include <stdio.h>
#include <time.h>
#define LEN 10
int* creatingArray();
void printingArray(int* array);
int main(void)
{
int* pointer_array = creatingArray();
printingArray(pointer_array);
getchar();
return 0;
}
int* creatingArray()
{
srand(time(NULL));
int array[LEN] = { 0 };
int* i = 0;
for (i = array; i < array + LEN; i++)
{
*i = rand() % 20;
}
return array;
}
void printingArray(int* array)
{
int* i = 0;
for (i = array; i < array + LEN; i++)
{
printf("\n%d\n", *i);
}
}

Pay attention to this code:
int* creatingArray()
{
// stuff
int array[LEN] = { 0 };
// more stuff
return array;
}
array is a local variable, so it gets destroyed when the function returns. You then have a pointer to a destroyed variable. The space where it was will (most likely) continue to hold the data you put there - until the memory gets reused for something else and overwritten.
and how to fix it if it eve/n possible?
Several options:
Make array a static variable. Then it will not be destroyed when the function returns. (This also means that every time you call creatingArray it will use the same array, instead of a new one)
Make array global.
Move array to main, and pass a pointer to it into creatingArray, instead of having creatingArray return one. Then, since it's a local variable in main, it will only be destroyed when main returns.
Use malloc to allocate some space that will not be cleaned up automatically when the function returns.

Related

pointers in functions don't return what I want

I have two functions, I need one to add a value to a variable and the other to print it, but the output is incorrect to what I expect.
What I do is define a function, passing a sum pointer as a parameter, in another function I create the variable that I will pass as a parameter and I invoke the new function passing that variable as an address, but when printing it it fails.
#include <stdio.h>
void test() {
int sum;
test2(&sum);
printf("%d",sum);
}
void test2(int *sumador) {
int i;
for(i = 0; i < 10; i++) {
sumador += i;
}
}
int main() {
test();
}
The problem is that you should dereference the pointer before summing with "i", like this:
*sumador += i;
This happens because "sumador" is a pointer and the content of the pointer is a memory address. In your original code you are adding "i" to the address stored in "sumador", what you actually want is to sum "i" with the content contained in the memory address stored in the pointer, which is the process we called dereferencing.
Another problem is that in function test make sure to initialize
the value of the variable sum.
int sum = 0;
Also, because test2 is called inside test, you should declare the function test2 above the function test, not below it, like this:
#include <stdio.h>
void test2(int *sumador) {
int i;
for(i = 0; i < 10; i++) {
*sumador += i;
}
}
void test() {
int sum = 0;
test2(&sum);
printf("%d",sum);
}
int main() {
test();
}
I hope I was able to help you,
have a nice day!

Use a function to change the contents of the array, i.e. multiply each number in the array by 2

Question
Use your function to change the contents of the array, i.e. multiply each number in the array by 2.
When your function has finished and your program continues in your main(), print the contents of your array in your main().
See if the changes made to the contents of the array in your function can be seen. If not, why?
Further
I'm trying to multiply the original array by 2 onto another array. Can anyone spot where I've went wrong?
#include <stdio.h>
#include <math.h>
#define SIZE 5
//function signatures
int getMultiples(int[]);
//main function
int main()
{
//main variables
int array[SIZE];
int multiples[SIZE];
printf("\nPlease enter 5 numbers into an array.\n");
for(int i = 0; i < SIZE; i++)
{
scanf("%d", &array[i]);
}
multiples[] = getMultiples(array);
printf("\nThis program will multiply all numbers by 2\n\n");
for (int i = 0; i < SIZE; i++)
{
printf("%d\n", multiples[i]);
}
return 0;
}
int getMultiples(int arr[])
{
//function variables
int i;
int multiples[SIZE];
for (i = 0; i < SIZE; i++)
{
multiples[i] = arr[i] * 2;
}
return multiples[];
}
This statement
multiples[] = getMultiples(array);
is syntactically and semantically invalid. This construction multiples[] is wrong and arrays do not have the assignment operator.
Also the definition of the function getMultiples is also wrong.
Again this statement
return multiples[];
is invalid.
What you are trying to do is to return the local array
int multiples[SIZE];
but the function return type is int. At least you needed to declare the return type as int *.
But in any case the local array that has automatic storage duration will not be alive after exiting the function.
If to use your approach then the function can look the following way
void getMultiples( int a1[], const int a2[], size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
a1[i] = 2 * a2[i];
}
}
and in main the function is called like
getMultiples( multiples, array, SIZE );
Pay attention to that the function definition should not depend on the magic number SIZE.
By the way in your assignment there is written
Use your function to change the contents of the array, i.e. multiply
each number in the array by 2.
It means that you need to change the source array,
In this case the auxiliary array multiples is redundant. The function could be defined the following way
void getMultiples( int a[], size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
a[i] *= 2;
}
}
and called in main like
getMultiples( array, SIZE );
You promise to return a single int.
int getMultiples(...);
You don't:
return multiples[];
You attempt to assign to a whole array (either a single int or an array....).
multiples[] = getMultiples(array);
That does not work in C.
And judging from what happens when trying your code, your compiler should have told you.

returning 2D array having error, need concept

I tried different methods but eventually got errors. Please give a solution and a brief explanation of the concept.
uint8_t **subBytes()
{
int i,j;
uint8_t r,c;
uint8_t t[4][4];
for(i=0;i<4;i++)
{
for (j=0;j<4;j++)
{
r = pt[p1][j] & 0xf0;
r = r >> 4;
c = pt[p1][j] & 0x0f;
t[i][j] = (uint8_t *) malloc(sizeof(uint8_t));
t[i][j] = sBox[r][c];
}
p1++;
}
return t;
}
int main()
{
uint8_t **temp;
temp = subBytes();
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
printf("%x ", temp[i][j]);
}
printf("\n");
}
}
This is my original code. Here, I used malloc, but then too it is not working.
the memory space alloced for your matrix is a LOCAL VARIABLE.
The scope of a LOCAL VARIABLE is only within that function.
When you returned it is discarded.
In your code it is uint8_t t[4][4].
t is discarded right after return t.
So you return nothing and may cause undefined behavior.
You should use malloc to alloc memory for your matrix not just declare it locally.
in code
uint8_t **t.
t = malloc(sizeof(uint8_t) * 16 ) //size of a 4x4 matrix
then use t as a two dimension array and return t.like
t[0][0] = 1;
don't forgot to free it after use it out side of the function.
free(t);
m is LOCAL VARIABLES. When add returns, m is DESTROYED!
You SHOULD NOT return the pointer or reference of local variables. Look the following code:
int foo() { return 1; }
int *bar() { int i = 1; return &i; }
When I call foo(), it returns 1.
When I call bar(), it try to return the local variables, i's address. But when bar() returns, the i variable is DESTROYED! So the return pointer become trash pointer. (Sorry, I don't know how to say that term in English;)
You should use like that:
void bar(int *ret) { *ret = 1; }
int i;
bar(&i); /* now i is 1 */
or
int *bar()
{
int *p = (int *)malloc(sizeof(int));
*p = 1;
return p;
}
int *pi = bar();
/* now *pi is 1 */
...
free(pi); /* You MUST free pi. If not, memory lack is coming~ */
(I recommend first one. the second one require free and it can be mistaken.)
When a variable is declared (statically allocated) within a function, it is placed on what is called the stack, which is only local to that function. When the program leaves that function's scope, the variable is no longer guaranteed to be preserved, and so the pointer you return to it is essentially useless.
You have three options to fix your error:
Don't do it
Simply declare the array in the same function as you use it, don't bother with trying to return a pointer from another function.
Pass a pointer to a variable local to main
A pointer to a variable local to main will be valid until main returns, so you could do this:
void subBytes(uint8_t t[4][4]){
//perform initialization of matrix on passed variable
}
int main(){
uint8_t temp[4][4];
subBytes(&temp);
//...
}
Dynamic Allocation
This will probably give you more errors than it will solve in this case, but if you are heartset on returning a pointer to a matrix, you could malloc() the memory for the array and then return it, but you would have to free() it afterwards.
In C, there are several ways to dynamically allocate a 2D array. The first is to create it as a single array, and operate on the indices to treat it as 2D.
//...
int *arr = (int *)malloc(rows*cols*sizeof(int));
for (int i = 0; i<rows; i++){
for (int j = 0; j<height; j++){
arr[i*height + j] = i*j; //whatever
}
}
return arr; // type is int *
//...
Note that in this method, you cannot use array[i][j] syntax, because the compiler doesn't know the width and height.
The second way is to treat it as an array of arrays, so store an array of pointers to other arrays.
//...
int **arr = (int **)malloc(rows*sizeof(int *));
for (int i = 0; i<rows; i++){
arr[i] = (int *)malloc(cols*sizeof(int));
}
arr[i][j] = 86; //whatever
return arr; //type is int **
//...
For further information, see: Pointer to Local Variable

How to get the information from a pointer [duplicate]

This question already has answers here:
Returning Arrays/Pointers from a function
(7 answers)
Closed 9 years ago.
Here is my code:
int *myFunction()
{
int A[3] = {1,2,3};
return A; //this will return the pointer to the first element in the array A
}
int main (void)
{
int A[3];
A = myfunction(); //A gets the return value of myFunction
for(int j=0; j==2; j++)
{
B[j] = 2* A[j]; //doubles each value in the array
}
printf("%d",B);
return 0;
}
But this does not work because the A that is returned is not the actual vector. How do I get the actual vector {1,2,3} in the main function?
The function myFunction allocates A, but this allocation only exists within the scope of the function. When the function returns the memory holding A is destroyed. This means that the function is returning a pointer to memory that has not been un-allocated.
The problem is that the variable A does not persist outside the function. You could use a global variable or pass a pointer to the buffer into myFunction
Global variable method:
static int A[3];
int* myFunction()
{
A[0] = 1; A[1] = 2; //etc
return A;
}
In this example, because A is a global, the memory pointed to by A persists throught your program's entire life time. Therefore it is safe to return a pointer to it...
As a side note, global variables should probably not be used in this way... it's a little clunky. The use of the static keyword means that A will not be accessible outside of this module (C file).
Pointer method:
void myFunction(a[3])
{
a[0] = 1; a[1] = 2; //etc
}
int main()
{
myA[3];
myFunction(myA);
// and continue to print array...
}
In this example the main() function allocates myA. This variable exists whilst the function is executing (it's an automatic variable). A pointer to the array is passed into the function, which fills the array. Therefore the main() function can get information from myFunction().
Another way to make the variable myA persist would be to allocate it on the heap. To do this you would do something like int *myA = malloc(sizeof(int) * NUMBER_OF_INTS_IN_ARRAY. This memory will then persist until you specifically desctroy it using free() or you program ends.
int A[3] = {1,2,3}; is being created on the stack, this is, it is a local array and it's memory can be used again after myFunction executes. You have to either make int A[3] static within myFunction or by placing it outside of all functions. Another option would be to create int A[3] within main and pass the address of A to myFunction so myFunction can directly modify the contents of A.
As is, your code isn't close to working anyway... your for loop is broken, you have undefined variables in main, you have function name mismatches, and your print isn't going to do what you want anyway...
The big problem as that you've got undefined behavior going on, you can't access A[] outside of the function where it was locally defined. The easiest way to rectify that is to use dynamic memory, malloc() some memory for A in your myFunction then use the values in main and free() the memory when you're done.
Here's the example fixing your other syntax issues:
int *myFunction()
{
int *A;
A = malloc(3 * sizeof(int));
A[0] = 1;
A[1] = 2;
A[2] = 3;
return A;
}
int main (void)
{
int *A = myFunction(); //A gets the return value of myFunction
int B[3] = {0, 0, 0};
int j;
for(j=0; j<3; j++)
{
B[j] = 2* A[j]; //doubles each value in the array
}
free(A);
printf("%d",B[0]);
return 0;
}
Pass the array to be filled as argument to the initisliser function along with its size:
size_t myFunction(int * A, size_t s)
{
int A_tmp[3] = {1,2,3};
size_t i = 0;
for (; i < s && i < sizeof(A_tmp)/sizeof(A_tmp[0]); ++i)
{
A[i] = A_tmp[i];
}
return i;
}
Then call it like so:
int main()
{
int myA[3];
size_t s = sizeof(myA)/sizeof(myA[0]);
size_t n = myFunction(myA, s);
if (n < s)
fprintf(stderr, "Caution: Only the first %zu of %zu elements of A were initialised.\n", n, s);
// and continue to print array...
}
#include <stdio.h>
int (*myFunction(void))[3]
{
static int A[3] = {1,2,3};
return &A;
}
int main (void){
int (*A)[3], B[3];
A = myFunction();
for(int j=0; j<=2; j++)
{
B[j] = 2 * (*A)[j];
}
for(int j=0; j<3;++j)
printf("%d ", B[j]);
return 0;
}

C - function returns an array

I'm writing a method that receives a number l and returns a vector of size l with random numbers. I have this code, but does not work
#include <time.h>
int makea (int z) {
int a1[z];
int i;
for (i = 0; i < tam; i++) {
a1[i]=srand(time(0));
}
return a1;
}
These are the errors that the compiler returns me
arrays1.c: In function 'makea':
arrays1.c:12: error: void value not ignored as it ought to be
arrays1.c:14: warning: return makes integer from pointer without a cast
arrays1.c:14: warning: function returns address of local variable
I think is a problem of pointers... but I'm not really sure
A few problems:
Your array is allocated on the stack, meaning that when your function exits, the memory you return will be invalid
In C, you cannot return an array from a function, it must first decay into a pointer.
So, to fix, use malloc and a pointer:
int *makea (int z) {
int *a1 = malloc(sizeof(int) * z);
int i;
srand(time(NULL));
for (i = 0; i < tam; i++) {
a1[i]= rand();
}
// remember to free a1 when you are done!
return a1;
}
Also note that using malloc can sometimes basically grant you the 'random number' scenario for free, negating the need to loop through the elements as the value returned from malloc is garbage (and thus random numbers).
However, also note that malloc is implementation-specific, meaning that an implementation could theoretically clear the memory for you before returning it.
Your best bet is:
Declare the array outside of the routine, and pass it in to initialize it:
void init_array (int a[], nelms)
Plan B is pass a pointer to a pointer, and have the routine allocate and initialize it
Like this:
void alloc_and_init_array (int **a_pp, int nelms)
{
*a_pp = malloc (sizeof (int) * nelms);
...
... or, equivalently ...
int *
alloc_and_init_array (int nelms)
{
int *a_p = malloc (sizeof (int) * nelms);
...
return a_p;
A local variable like your array is allocated on the stack. At function return it is removed from the stack, so the pointer you return points to an unallocated memory location.
You have to allocate the array with malloc() or pass an already existing array to the function.
#include <time.h>
int makea (int z) {
int *a1 = (int*)malloc(z*sizeof(int));
int i;
for (i = 0; i < tam; i++) {
a1[i]=srand(time(0));
}
return a1;
}
IMPORTANT: remember to free memory allocated somewhere outside, when you do not need it anymore.
Well, first off your function says that it returns an int, yet you want to return an array, so that is wrong. Of course, you can't return an array in C either...
Second, you will have to return a pointer. You cannot copy arrays via assignment or assign a new value to an array at all in C, so your function won't be very useful. Either return an int* or take an int** as an output argument and initialize it in your function.
Also, your array is locally allocated, so even if the compiler didn't complain you would be returning invalid memory.
int makea (int size, int **out_array) {
int *temp, i;
if(!out_array)
return 0;
temp = malloc(sizeof(int) * size);
if(!temp)
return 0;
srand(time(0));
for (i = 0; i < size; ++i)
temp[i] = rand();
*out_array = temp;
return 1;
}
int main() {
int *arr;
if(!makea(10, &arr)) {
printf("Failed to allocate array");
return -1;
}
return 0
}
Another note:
temp[i] = srand(time(0));
That is wrong. srand seeds the random number generator, but does not return a random number. You call srand to input the seed and then call rand to get a random number.

Resources