Why does the order of these scanf’s make a difference in the outcome?

Asked

Viewed 110 times

3

The program sums up x1 and x2 and puts the result in x1. It doesn’t work if x1 be read before x2. But if you reverse this order, it works.

#include <stdio.h>
#include <stdlib.h>

unsigned char x1,x2;

void soma() {
    x1 = x1 + x2;
}

int main()
{    
    /* Carga das variaveis que estao mapeadas na memoria */
    printf("Valor de x1 = "); scanf("%d", (int*)&x1);
    printf("Valor de x2 = "); scanf("%d", (int*)&x2);
//    printf("Valor de x1 = "); scanf("%d", (int*)&x1);

    soma();

    printf("x1=%d, x2=%d\n", x1, x2);
    return 0;
}
  • 1

    Are you curious why this is happening or you’re doing something and you’re worried because it’s not working? You know you’re doing a lot of things you shouldn’t be doing under normal conditions?

2 answers

7


The problem is that your variables are declared as char, but you do the reading as int. Thus, the function scanf reads more than 1 byte and invades variable memory x2 (that as it was stated later, is soon after in memory).

Using Visual Studio, for example, you can see that the memory addresses of each of the variables are followed (x1 in 0x00ff8134 and x2 in 0x00ff8135, in my example, and with 1 byte difference since the variables are allocated as char):

inserir a descrição da imagem aqui

Dai, if you do the reading to x2 before, you can notice that the function changes 4 bytes (I compiled for 32 bits).

Before the scanf in x2:

inserir a descrição da imagem aqui

After the scanf in x2 (with input value 7):

inserir a descrição da imagem aqui

The same will be true for reading to x1 that you do next, only that then, as the memory is updated in 4 bytes, will be changed the original value of x2 coming right after (observing: the start address on the following screens is the variable x1, but he is no longer the same as before because I captured the screens in a new run).

Before reading a value for x1 (with input value 2, in my case):

inserir a descrição da imagem aqui

After reading a value to x1 (notice how the memory area of x2 was amended):

inserir a descrição da imagem aqui

That is why the function scanf is considered unsafe and its use is advised against. To perform my test, for example, I had to use:

#define _CRT_SECURE_NO_WARNINGS

Without this definition, the compiler itself (in my case, Visual Studio 2012) advises to use an alternative from Microsoft called scanf_s.

6

scanf("%d",...) will read and put an integer value (example 4 bytes) at the address you are given.

Since the variable you’re reading to has only one byte (char), the poor neighbor variable gets run over. This kind of thing can cause unpredictable effects (e.g., Segmentation fault)

  • 2

    +1 by the "deviant of the neighboring variable" eheh

  • 1

    @Omni, thank you for understanding my impractical language :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.