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.

7
  • 2
    Possible duplicate of Can a local variable's memory be accessed outside its scope? and many other similar questions Commented Aug 10, 2017 at 15:16
  • Edited the answer with console values Commented Aug 10, 2017 at 15:17
  • Never post pictures of text when you can post the text. Commented Aug 10, 2017 at 15:18
  • Alright ! And I am returning values not address Commented Aug 10, 2017 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 Commented Aug 10, 2017 at 15:20

3 Answers 3

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.
Sign up to request clarification or add additional context in comments.

2 Comments

This is why is called Undefined Behaviour.
@Swarnveer Undefined behavior means anything can happen, including "appearing to work"
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;
}

5 Comments

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.
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.
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.
Recommend int *op1 = malloc(sizeof *op1 * (input1_size - 1)); and insure input1_size > 2.
@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 is the latest publicly available draft.
-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...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.