-1

I tried to understand C behavior and found some weird things. I debugged and found out that table values are correct until calling printf. I create a void function to test whether it is a problem of scope but after calling this function the table values still remained correct. I wonder now if printf delete previous local variables.

#include <stdio.h>
#include <stdlib.h>
void invertTable(int** tableau,int size){
    int temp[size];
    for(int i = 0; i < size; i++)
    {
        temp[i]=-1*tableau[0][i];
    }
    tableau[0]=temp;
}
void test(){

}
int main(int argc, char const *argv[])
{
    int* table=(int*)malloc(5*sizeof(int));
    table[0]=1;
    table[1]=2;
    table[2]=3;
    table[3]=4;
    table[4]=5;
    invertTable(&table,5);
    test();
    for(int i = 0; i < 5; i++)
    {
        //Here is the problem
        printf("\n %d \n",table[i]);
    }
    free(table);
    return 0;
}

Expected -1 -2 -3 -4 -5

Output: -1 1962295758 1 1962550824 1962295741

  • 1
    When you assign tableau[0] = temp; the variable temp is local so it is freed after function returns. So your table points to an unallocated memory. Then the behavior is undefined, the call to printf probably reallocates some memory where temp was, so you see the junk... –  Apr 08 '19 at 09:22
  • See https://www.geeksforgeeks.org/return-local-array-c-function/ – Déjà vu Apr 08 '19 at 09:23

3 Answers3

2

Your issue is not related to printf, it's due to a bug in your code where you try to use memory you're not supposed to.

In this line in your invertTable function:

 tableau[0]=temp;

You are pointing the table pointer in your main() function to the local temp variable.

Your temp array goes out of scope when the invertTable function ends, so you end up with a dangling pointer and you can't use that memory anymore- doing so is undefined behavior.

You could instead dynamically allocate memory, which will stay valid after invertTable ends:

int *temp = malloc(sizeof(int) * size);
for(int i = 0; i < size; i++)
{
    temp[i]=-1*tableau[0][i];
}
//deallocate previous allocation
free(tableau[0]);
tableau[0]=temp;
nos
  • 223,662
  • 58
  • 417
  • 506
0

Your problem is not related to printf it's indeed invertTable which is the culprit.

When dealing with arrays table is equal to &table[0] so in this case, you don't need to send the address of tableau.

#include <stdio.h>
#include <stdlib.h>
void invertTable(int *tableau,int size){
  for(int i = 0; i < size; i++)
    {
      tableau[i] = -1 * tableau[i];
    }
}
void test(){

}
int main(int argc, char const *argv[])
{
  int* table = (int*) malloc(5 * sizeof(int));
  table[0]=1;
  table[1]=2;
  table[2]=3;
  table[3]=4;
  table[4]=5;
  invertTable(table,5);
  test();
  for(int i = 0; i < 5; i++)
    {
      //Here is the problem
      printf("\n %d \n",table[i]);
    }
  free(table);
  return 0;
}

this will do what you are looking for. Plus, you don't need to use any temporary variable either.

By the way, temp was temporary, it was not allocated on the heap so it was destroyed when invertTable returned.

Swann
  • 2,413
  • 2
  • 20
  • 28
-1

To have correct output you should change

int temp[size] to int* temp = *tableau or to int* temp = (int*) malloc(sizeof(**tableau) * size).

These solutions work because *tableau and or the memory allocated by malloc is not destroyed after invertTable.

Normally temp should be destroyed after invertTable function and making tableau[0] a dangling pointer then the system may reallocate the memory where temp pointed to. Thus, this part of memory may now contain random data. These data are probably what you got at execution time.

Michaël Randria
  • 453
  • 1
  • 5
  • 21