Erroneous result C ++

1

I have a problem in c ++ I'm trying to do a simple calculation using POO but the result is wrong or close to what should be:

#include <iostream>

using namespace std;

class productos{

public:

productos(int x,int y){
x=n;
y=m;
cout<<x*y;
}
int producto1(){

    return n*m;//Usando esta funcion tampoco arroja el resultado
}



private:
int m; 
int n;
int mil;




};
int main()
{
    productos dos(2,2500);



return 0;
}

The result is:

-1074975852-1074975852

I also had an error initializing:

int m=2500; 

I am a beginner in c ++ and I have other console programs that are practically identical, maybe with more functions but basically the same.

What did I do wrong? and how do I solve it?

PS: I already tried sublime text codeblocks and an online compiler and the result is the same.

    
asked by wonderly gonzalez 23.08.2017 в 07:26
source

3 answers

2

Problem with uninitialized variables

You are making a very common mistake and is making use of a variable without having been previously initiated to a value.

void productos(int x, int y) {
  x = n;
  y = m;
  std::cout << x * y;
}

As you can see here you are assigning to x and y the values of n and m , overwriting the values that you have passed to the constructor, but these do not have values initially, so their initial content It is indeterminate.

private:
 int m;
 int n;
 int mil;

Solution using the class correctly

If I reorder the code to do what you want, this would be the result:

#include <iostream>

class productos {
 public:

  productos(int x, int y) {
    n = x;
    m = y;
    std::cout << "En el constructor: " << x * y << std::endl;
 }

  int producto1() {
    return n * m;
  }

 private:
  int m;
  int n;
  int mil;
};

int main() {
  /* Creo una instancia de productos pasando al constructor (2, 2500) */
  productos producto (2, 2500);
  /* Uso el método producto1 para calcular el resultado de la multiplicación */
  std::cout << "El resultado del producto es: " << producto.producto1() << std::endl;
  return 0;
}

The result of the execution is:

En el constructor: 5000
El resultado del producto es: 5000

Error analysis with valgrind

Valgrind results of your code:

==30015== Memcheck, a memory error detector
==30015== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==30015== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==30015== Command: ./pruebas_stack
==30015== 
==30015== Conditional jump or move depends on uninitialised value(s)
==30015==    at 0x4EBFCDE: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==30015==    by 0x4EC02BC: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==30015==    by 0x4ECC06D: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==30015==    by 0x4008DB: productos::productos(int, int) (in ./pruebas_stack)
==30015==    by 0x40084A: main (in ./pruebas_stack)
==30015== 
==30015== Use of uninitialised value of size 8
==30015==    at 0x4EBFBC3: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==30015==    by 0x4EBFD05: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==30015==    by 0x4EC02BC: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==30015==    by 0x4ECC06D: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==30015==    by 0x4008DB: productos::productos(int, int) (in ./pruebas_stack)
==30015==    by 0x40084A: main (in ./pruebas_stack)
==30015== 
==30015== Conditional jump or move depends on uninitialised value(s)
==30015==    at 0x4EBFBCF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==30015==    by 0x4EBFD05: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==30015==    by 0x4EC02BC: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==30015==    by 0x4ECC06D: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==30015==    by 0x4008DB: productos::productos(int, int) (in ./pruebas_stack)
==30015==    by 0x40084A: main (in ./pruebas_stack)
==30015== 
==30015== Conditional jump or move depends on uninitialised value(s)
==30015==    at 0x4EBFD33: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==30015==    by 0x4EC02BC: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==30015==    by 0x4ECC06D: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==30015==    by 0x4008DB: productos::productos(int, int) (in ./pruebas_stack)
==30015==    by 0x40084A: main (in ./pruebas_stack)
==30015== 
-251679360
==30015== 
==30015== HEAP SUMMARY:
==30015==     in use at exit: 0 bytes in 0 blocks
==30015==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==30015== 
==30015== All heap blocks were freed -- no leaks are possible
==30015== 
==30015== For counts of detected and suppressed errors, rerun with: -v
==30015== Use --track-origins=yes to see where uninitialised values come from
==30015== ERROR SUMMARY: 20 errors from 4 contexts (suppressed: 0 from 0)

Where I highlight the meaning of:

  • Use of uninitialized value of size 8 : Use of a value without initializing size 8 .
  • Conditional jump or move depends on uninitialized value (s) : Conditional jump depends on an uninitialized value .

Valgrind results after correcting the problem:

==29964== Memcheck, a memory error detector
==29964== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==29964== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==29964== Command: ./pruebas_stack
==29964== 
5000
==29964== 
==29964== HEAP SUMMARY:
==29964==     in use at exit: 0 bytes in 0 blocks
==29964==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==29964== 
==29964== All heap blocks were freed -- no leaks are possible
==29964== 
==29964== For counts of detected and suppressed errors, rerun with: -v
==29964== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
    
answered by 23.08.2017 / 07:52
source
1

The problem is in the assignment within productos(int x, int y) since you are assigning these variables within the function, perhaps you inverted the order of the variables; You have 2 options:

  • In the products function you receive the variables n and m productos(int n; int m)
  • In the products function you leave it as you have it (receiving x and y) but you modify the assignment n = x and m = y and print cout<<n*m
  • I did it with the form 1:

    #include <iostream>
    
    class productos{
    
        public:
    
        productos(int n,int m){
            x=n;
            y=m;
            std::cout<< x*y;
        }
    
        private:
        int x;
        int y;
    };
    
    int main()
    {
        productos(2,2500);
        return 0;
    }
    

    The values thrown by -1074975852-1074975852 are because it took values from the memory when you made allocations x = n and n did not have any value.

        
    answered by 23.08.2017 в 07:49
    0

    To avoid the initialization errors of variables, which I will not detail because you already have other answers in which you comment on the problem, it is preferable to initialize all the possible member variables in the initialization section within the constructor, I explain:

    productos(int x, int y)
      : n(x), m(y)
    {
      std::cout << "En el constructor: " << x * y << std::endl;
    }
    

    Why? Two basic reasons:

    • In the case of initializing classes, you avoid redundant operations:

      struct Test
      {
        std::string a;
      
        // Aqui se hace
        // Llamada al constructor de std::string
        // Llamada al operador de asignación std::string = std::string
        Test(std::string const& var)
        {
          a = var;
        }
      
        // Aqui se hace
        // Llamada al constructor copia std::string(std::string const&)
        Test(std::string const& var)
          : a(var)
        { }
      };
      
    • As a general rule, avoid silly mistakes:

      struct Test
      {
        int a;
      
        // Error de compilacion
        Test(int b)
          : b(a)
        { }
      
        // ok
        Test(int b)
          : a(b)
        { }
      
        // ok. Equivalente a this->a = a
        Test(int a)
          : a(a)
        { }
      };
      
    answered by 23.08.2017 в 08:25