2

I am making this program in which my main function calls a function which returns an array after the calculation. I checked already that calculation is right inside the local function. But when I return that array to 'main' function then I only can print the correct value one time and it prints wrong value all other times.

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
int* getJoinedPipes(int input1_size, int* input1,int* output_size){
  int i,j,temp;
  int op1[input1_size-1];
  *output_size = input1_size - 1;
  for(i=0; i<input1_size; i++){
    for(j=i+1; j<input1_size; j++){
      if(input1[i] > input1[j]){
        temp     = input1[i];
        input1[i] = input1[j];
        input1[j] = temp;
      }
    }
  }

  op1[0]=input1[0] + input1[1];
  for(i=1;i<input1_size-1;i++){
    op1[i] = op1[i-1]+input1[i+1];
  }
  //printf("%d\n",op1[2]);

  return op1; 
}

int main() {
  int output_size;
  int* output;

  int ip1_size = 0;
  int ip1_i;
  scanf("%d\n", &ip1_size);
  int ip1[ip1_size];
  for(ip1_i = 0; ip1_i < ip1_size; ip1_i++) {
    int ip1_item;
    scanf("%d", &ip1_item);

    ip1[ip1_i] = ip1_item;
  }
  output = getJoinedPipes(ip1_size,ip1,&output_size);
  printf("a==%d\n",output[0]);
  printf("a==%d\n",output[0]);
  printf("a==%d\n",output[0]);
  int output_i;
  for(output_i=0; output_i < output_size; output_i++) {
    printf("%d\n", output[output_i]);
  }

  return 0;
}

Output should be

5
9
15

But in the console, it's showing the following (after dry run). See the image

a==5    
a==1943372821    
a==1943372821    
1943372821    
17    
6356632

You can see first time its giving correct value (5) and later for same print its giving garbage values.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
Swarnveer
  • 490
  • 5
  • 23
  • 2
    Possible duplicate of [Can a local variable's memory be accessed outside its scope?](https://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) and many other similar questions – Jabberwocky Aug 10 '17 at 15:16
  • Edited the answer with console values – Swarnveer Aug 10 '17 at 15:17
  • Never post pictures of text when you can post the text. – Jabberwocky Aug 10 '17 at 15:18
  • Alright ! And I am returning values not address – Swarnveer Aug 10 '17 at 15:18
  • 2
    `op1` __is__ an address, not a value. It's the address of the first element of the local array `op1`. `op1` ceases to exist once you exit from the function. Read the answer with the most upvotes of [this question](https://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) – Jabberwocky Aug 10 '17 at 15:20
  • @MichaelWalz to be pedantic `op1` is an array. When you `return op1;` it returns a pointer to the first element - `op1` "decays" into a pointer in many contexts, including this one. – Kevin Aug 10 '17 at 15:22
  • Keep in mind that you **cannot** return an array from a function, nor can you pass an array as an argument. You can, as you try to do here, return or pass a pointer to an array's initial element. (The length of the array has to be specified in some other way, since the pointer doesn't carry that information.) – Keith Thompson Aug 10 '17 at 15:38

3 Answers3

5

op1 is an automatic array. You cannot return it and use it outside its scope.

op1 exists only within getJoinedPipes, if you return it, the result is Undefined Behaviour.

To fix it you can either:

  • pass op1 as a parameter to getJoinedPiped
  • allocate op1 on the heap dynamically. You you do that, you can safely return op1 but you have to remember to free it when you don't need it.
Davide Spataro
  • 7,319
  • 1
  • 24
  • 36
3

You are returning pointer to a local variable object whose lifetime has ended yet when you are trying to get its values -> horrible mistake and undefined behaviour.

If you want to return an array from function, allocate it dynamically via malloc, and dont forget to free it after you are done with that array. You should also check return value of malloc if you got memory you asked for.

Correct

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
int* getJoinedPipes(int input1_size, int* input1,int* output_size){
int i,j,temp;
int * op1 = (int *)malloc(sizeof(int) * (input1_size-1));
*output_size = input1_size - 1;
for(i=0; i<input1_size; i++){
    for(j=i+1; j<input1_size; j++){
        if(input1[i] > input1[j]){
            temp     = input1[i];
            input1[i] = input1[j];
            input1[j] = temp;
        }
    }
}

op1[0]=input1[0] + input1[1];
for(i=1;i<input1_size-1;i++){
    op1[i] = op1[i-1]+input1[i+1];
}
//printf("%d\n",op1[2]);

return op1;
}

int main() {
int output_size;
int* output;

int ip1_size = 0;
int ip1_i;
scanf("%d\n", &ip1_size);
int ip1[ip1_size];
for(ip1_i = 0; ip1_i < ip1_size; ip1_i++) {
    int ip1_item;
    scanf("%d", &ip1_item);

    ip1[ip1_i] = ip1_item;
}
output = getJoinedPipes(ip1_size,ip1,&output_size);
printf("a==%d\n",output[0]);
printf("a==%d\n",output[0]);
printf("a==%d\n",output[0]);
int output_i;
for(output_i=0; output_i < output_size; output_i++) {

    printf("%d\n", output[output_i]);

}

free(output);
return 0;
}
kocica
  • 6,412
  • 2
  • 14
  • 35
  • Returning pointer to local variable (degraded from array) is different than returning (the value of) a local variable. The latter is how your answer could be misread. The first is the problem. I recommend to rephrase. – Yunnosch Aug 10 '17 at 15:20
  • The problem isn't that the array object is out of scope; that just refers to the region in which its name is visible. The problem is that the returned pointer points to an object whose *lifetime* has ended. If `op1` where defined as `static`, it would be valid to return a pointer to it (or to its initial element), even though it would still be out of scope. – Keith Thompson Aug 10 '17 at 15:35
  • Thank you for correction @KeithThompson, i have written that variable is _out of scope_ i thought its same as _which lifetime has ended_. Am i wrong? Thank you for kind explanation. – kocica Aug 10 '17 at 15:38
  • Recommend `int *op1 = malloc(sizeof *op1 * (input1_size - 1));` and insure `input1_size > 2`. – chux - Reinstate Monica Aug 10 '17 at 15:47
  • @FilipKočica: *Scope* is the region of program text over which an identifier is visible. *Lifetime*, or *storage duration*, is the span of time during execution in which an object exists. See section 6.2 of the C standard; [N1570](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) is the latest publicly available draft. – Keith Thompson Aug 10 '17 at 17:20
-2

You should check your indentation... apart from that, I guess the problem could arise because the array you output in your function is created on the function stack. So what you get as an output array is a reference on the stack of your joinedPipes-function. Try to pass your array as an argument to the function and not create it as a return value.

Hope that does the trick...

drssdinblck
  • 260
  • 2
  • 11