pointer problem

Hi everyone , i'm a newbie . I have a problem with my program , i hope you will show me the way how to solve it. Here's my code :
#include<iostream>
using namespace std;
int* findmax(int *a, int *b)
{
return *a > *b ? a : b;
}
int* findmin(int *a, int *b)
{
return *a < *b ? a : b;
}
void deliver(int *&x)
{
x = new int;
}
void input(int *A , int &n)
{
do {
cout << "\nEnter the number of the array: ";
cin >> n;
if (n <= 0) cout << "Error";
} while (n <= 0);
for (int i = 0; i <= n; i++)
{
cout << "A[" << i << "] = ";
cin >> A[i];
}

}
void output(int *A , int n)
{
for (int i = 0; i <= n; i++)
{
cout << A[i] << "\t";
}
}
int sum(int *a, int n)
{
int s = 0;
for (int i = 0; i <= n; i++)
{
s += a[i];
}
return s;
}
int main()
{
int *a, *b,n;
deliver(a);
deliver(b);
int *A = new int[n]; // (*)
cout << "Enter a and b : "<<endl;
cin >> *a >>*b;
int *max = findmax(a, b);
int *min = findmin(a, b);
cout << "max: " << *max << "\tmin: " << *min;
input(a, n);
output(a, n);
cout << "Sum is :" << sum(a, n);
delete[] A;
delete a;
delete b;
system("pause");
return 0;
}

// when i debug my program , it send a notification that tells "uninitialized local variable'n' used (line (*))" . Please show me how to fix it ,i'd be very gratefull if you can help me do that . Thanks a lot .
int main()
{
int *a, *b,n; <--------------- N has no value.
deliver(a);
deliver(b);
int *A = new int[n]; // (*) <-------------- N has no value.

you should get N from the user, or assign it something before you try to allocate memory using its value.

It actually has a value, but it could be zero, negative, or some huge thing, ... its basically whatever junk was in that spot in ram that n took over when it was created.
Last edited on
Initialise n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main()
{
    int* a ; // it is a good idea to declare only one variable in one statement.
    deliver(a) ; // it's ok for a to be uinitialised here; 
                 // deliver assigns a value to a (and it does not use the previous value of a)
                 // however, a meticulous programmer may use abundant caution and write:
                 // int* a = nullptr ;

    int* b ;
    deliver(b) ;

    // int n = 22 ; // *** initialise n before using it 
    std::size_t n = 22 ; // better: use std::size_t to specify the size
                         // http://en.cppreference.com/w/cpp/types/size_t 
    
    // int* A = new int[n] ; // avoid using names which differ only in case
    int* ptr = new int[n] ; // better: use a distinct, semantically richer, name

    // ... 
}



> It actually has a value, but it could be zero, ...

No. As per the standard, examining the value of an uninitialised int is undefined behaviour.

In practice, the undefined behaviour may be manifested on implementations which have trap representations of integers.
Last edited on
in practice, I don't know of any compiler that does not just assign a memory location to the variable and leave the bytes that happened to be there intact simply because this is efficient. In functions, this is just on the call stack so you can pick up previous values if running the same function in a tight loop, and even stranger effects with recursion. It can be amusing to play with this, but its certainly not reliable or safe to do. A lot of coders initialize everything upon creation for safety. You don't want to use any uninitialized variable, is the bottom line.

The standard does say it is undefined, you are correct.

> in practice, I don't know of any compiler that does not just assign a memory location to the variable
> and leave the bytes that happened to be there intact simply because this is efficient.

If the address of a non-volatile local variable is never used, the "as-if" rule allows the compiler to store the variable in a register instead of an actual location in memory.

On the widely used IA64 architecture, each "64-bit" register has 65 bits; the 65th bit (which C++ does not treat as part of the value representation) is the "NaT bit"; this bit is set when a valid value has not been placed in the register. (This may happen when a register is spilled; the value in the register immediately after it is spilled may be NaT.) An uninitialised local variable passed (via a register) to a function may trigger the trap representation on x86-64.

For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int foo(int,int,int,int) ; // not defined to disable inlining

int function_like_foo( int a, int b, int c, int d ) 
{ 
  // function ike foo: expects initialised values in registers edi, esi, edx, ecx
  return a+b+c+d ; 
}

int bar()
{
  int x = 5 ; // x is optimised away
  
  // tail call with 5, 5, 5, 5 in registers edi, esi, edx, ecx
  return foo(x,x,x,x) ; 
}

int bar_ub() // silence serious warnings about uninitialised variable (no -Wall -Wextra)
{
  int x ; // uninitialised variable 
  // ergo uninitialised values in registers edi, esi, edx, ecx
  // unless the caller of bar_ub set initialized values into these registers,
  // foo() would encounter a trap representation for integers
  // eg. on windows, the kernel would trap this an throw STATUS_REG_NAT_CONSUMPTION 
  return foo(x,x,x,x) ; 
}


function_like_foo(int, int, int, int):              # @function_like_foo(int, int, int, int)
        lea     eax, [rdi + rsi]
        add     eax, edx
        add     eax, ecx
        ret

bar():                                # @bar()
        mov     edi, 5
        mov     esi, 5
        mov     edx, 5
        mov     ecx, 5
        jmp     foo(int, int, int, int)              # TAILCALL

bar_ub():                             # @bar_ub()
        jmp     foo(int, int, int, int)              # TAILCALL

https://godbolt.org/g/p3UibH
Topic archived. No new replies allowed.