C4700: uninitialized local variable - c++

When I compile this code it says "error C4700: uninitialized local variable 'b' used". I'm not sure what I have to do now to fix this problem. I'm neither an IT student or technican but I very like to learn C++ and I'm learning it by myself. I've been on this for 1 day.
Many thanks
#include <stdio.h>
#include <iostream>
//A.
//1--
void InputArray(int *a, int &n)
{
printf("Insert n = ");
scanf("%d", &n);
a = new int[n];
for (int i=0; i<n; i++)
{
printf("Enter the key's a[%d] values: ", i);
scanf("%d",&a[i]);
}
}
void main()
{
int *b, m;
InputArray(b, m);
}

b is passed by value, which means a copy will be made, but since it's not initialized, you get the warning. Simply initialize it:
int *b = nullptr;
or
int *b = NULL;

If you want the function to modify the caller's variable, then pass by reference:
void InputArray(int *&a, int &n)
^
Your version passes the uninitialised pointer by value; the function modifies a local copy of it, but leaves b in its uninitialised state.

The pointers are not default initialized, so your variable b is uninitialized, this is the source of error. You have to initialize this variable to fix this:
void main()
{
int *b = NULL, m;
InputArray(b, m);
}
After you fix this there is additional problem in your code. It seems from the way you call a function that you expect to persistently change pointer b passed into it, so that b will point into memory allocated with new after function returned. But you pass a pointer by value what means changes made in function will not be reflected in original variable b which will still point to what it pointed before the call to a function. (the array will be allocated inside function and will stay in memory after function returned but you will leak this memory as b won't point into it). To fix this you have to pass pointer by reference:
void InputArray(int*& a, int& n)
Also: where is delete? Remember: mapping new to delete is bijection: every new corresponds to single delete placed somewhere in code.

First of all, did you learn how to use an pointer correctly ? because if you know how to use pointer u should know that when you declare a pointer you need to be initialized to NULL before you can use it, correct me if i'm wrong.
Example
int *b = nullptr;
int *b = NULL;
int *b = 0;
int *b(0);
It's all the same thing but in an different way

Related

Unable to dereference a pointer pointing to an array

I have passed pointer to a pointer as a parameter to function and the goal is to make an array inside of that function. I have done that step properly and also inside of the function checked the *address and value of the array(local) as well as pointed by the pointer(op_ptr_array_) and they are the same(as desired).
But the problem is occurring while I want to dereference the provided pointer(op_ptr_array). The values are wrong while addresses are matched with the pointed array(local).
My idea is that as the address of op_ptr_array(pointer passed to the function) is equal to the local and op_ptr_array_ (array and pointer inside of the function) so using a for loop *(op_ptr_array+i) will provide me the result where i < op_size.
The approach I have taken is as follows:
#include <iostream>
void op_calculation(unsigned int* ip_ptr_array_,
unsigned int ip_size_,
unsigned int** op_ptr_array_,
unsigned int* op_size_)
{
*(op_size_) = ip_size_ + 2;
std::cout<<"op_size_ address: "<<op_size_<<std::endl;
std::cout<<"op_size_ value: "<<*(op_size_)<<std::endl;
unsigned int local[*(op_size_)];
std::cout<<"making local array to be pointed by op_ptr_array_\n";
for (unsigned int i = 0; i< *(op_size_); i++)
{
local[i]=i+1*3;
std::cout<<local[i]<<" ";
}
std::cout<<"\n";
*op_ptr_array_ = &local[0];
local[3] = 87; // for checking pointer charecter
for (unsigned int i = 0; i < *(op_size_); i++)
std::cout<<"array address: "<<&local[i]<<" ,op_ptr_array address: "<<(*op_ptr_array_)+i<<" ,val of array: "<<local[i]<<" ,val at op_ptr_array: "<<*((*op_ptr_array_)+i)<<std::endl;
// here value and addresses are same which is desired
}
int main()
{
unsigned int ip_size = 10;
unsigned int* ip_ptr_array = new unsigned int[ip_size];
unsigned int op_size;
unsigned int* op_ptr_array;
for(unsigned int i = 0; i < ip_size; i++)
{
ip_ptr_array[i] = i+2*2;
}
op_calculation(ip_ptr_array,
ip_size,
&op_ptr_array,
&op_size);
std::cout<<"Value printing after operation of op_calculation function\n";
std::cout<<"op_size: "<<op_size<<std::endl;
std::cout<<"op_ptr_array\n";
for(unsigned int i = 0; i < op_size; i++)
std::cout<<"Address: "<<(op_ptr_array+i)<<" , Value: "<<*(op_ptr_array+i)<<"\n";
/* Here only addresses are same with `local array` and
address pointed by op_ptr_array_ pointer` which you will find in op_calculation
function but values are different*/
std::cout<<"\n";
return 0;
}
Any idea where I am making the mess is highly appreciable.
Variable local is being declared as a local variable (i.e. on the stack). This falls out of scope when the function op_calculation exits, which means that the memory originally used to allocate local may be used for something else.
This can be corrected by converting local to a pointer and using new to allocate memory for the array’s contents or by declaring local as static, which will place the contents elsewhere in RAM. Keep in mind, if you use static any future calls to op_calculation will overwrite the contents of the array, even if it is still in use elsewhere. This would not be a problem if you used new, but if you use new you will need to remember to deallocate the array using delete[] when it is no longer needed.

New operator outside main function - C++

Why this code is working:
//Things
int **A;
main(){
//things
A = new int*[n];
for (int i = 0; i < n; i++) {
A[i] = new int[m];
}
// things
}
And this code isn't working:
//Things
int **A;
void functionOutsideMain(int **A,int n, int m){
A = new int*[n];
for (int i = 0; i < n; i++) {
A[i] = new int[m];
}
}
main(){
//Things
functionOutsideMain(A,n,m);
//Things
}
When I use new operator outside main function in a separate function it won't work.
But if I use new operator inside main funcion it works.
Can you explain me why this is happening?
or
If I'm doing something wrong.
In the first example, A is just a global variable, which main() uses directly.
In the second example, functionOutsideMain() has its own A parameter which it uses, whereas main() still uses the global A variable instead.
functionOutsideMain() takes its A parameter by value. When main() passes in the global A variable to functionOutsideMain(), a copy of that A is made, and so any value that functionOutsideMain() assigns to its A parameter will not be applied to the global A variable, which is why main() does not see the change.
To do what you are attempting, you need to have functionOutsideMain() take its A parameter by reference instead:
void functionOutsideMain(int** &A, int n, int m)
Now, any value functionOutsideMain() assigns to its A parameter will be assigned to the global A variable, and thus will be seen by main().
Hey I didn't get what you meant by not working, but the possible solutions to the problems could be
No need to pass A again to functionOutsideMain since A is already global
When you pass A to functionOutsideMain, the actual parameter A becomes the formal parameter A, and now here's the problem, in C there is only pass by value(unlike pass by reference in C++). So when you pass A to the function, a new pointer gets created in the function and when you allocate a chunk of memory to it, the new pointer points to that memory and not the old pointer that you are using in main function.
One possible solution for this would be
void function_outside_main(int ***A, int n, int m) {
int **Aptr = (*A);
// And then use Aptr to allocate memory as you did
}
Else don't pass A as function parameter since it's a global variable

in this really allowed function or we have undefined behavior

for swap function we have two choice:
ref-style:
void swap (int &a, int &b)
{
int temp;
temp = b;
b = a;
a = temp;
}
and pointer-style:
void swap (int *a, int *b)
{
int temp;
temp = *b;
*b = *a;
*a = temp;
}
ref-style absolutely legal but pointer-style have some issue, when we try to use
this function variables pass by value not by reference-even they are pointers-
in fact we try to use memory of a local variable outside its function,
and may by in some day in some machine we have undefined behavior ,also the code works for examples:
In this code:
main()
{
//
{
int i=12;
int *j=&i;
}
//in this area, there is not variables i and j, but phisically threre is
// unsafe-relationship between this address: &i and what point to (12) ,
//any more logic according to this assumtion may be work
//but not safe -in the scene of undefined behavior-
I don't know where you got the sentence about outside a function from. You shouldn't trust them, since that sentence is wrong.
It should be "accessing a local variable or a parameter after the function has returned invokes undefined behavior". (These are my own words.)
To get the official wording, look in the C++ standard. The keywords to look for are lifetime, storage duration and undefined behavior.

C++ Class pointer is not saving anything.

The following is a small scale example of the problem I am facing. In the example below I use int pointers but in my own code I am really using a pointer to another class (a node class).
The problem appears to be that I am using a call by value pointer (if there is such a thing). I don't know, I thought pointers were by reference. I do need to be able to pass multiple pointers to the method and I do not really want to write a specific method for each pointer. When I run the code, of course, I get some kind of error because it is trying to access a pointer that has not been allocated.
I do not understand why it would not initialize the correct pointer if I pass the specific pointer I want.
Any help would be greatly appreciated.
#include <iostream>
using namespace std;
class Test {
private:
int *p1;
int *p2;
int sizeP1;
int sizeP2;
public:
int* getIntPointer() {return p1;}
void initializeP1(int *ip,int n){
sizeP1=n;
ip=new int[n];
for(int i=0;i<n;i++)
p1[i]=i;
}
void printP1() {
for(int i=0;i<sizeP1;i++)
cout<<p1[i]<<" ";
}
};
int main() {
Test t;
t.initializeP1(t.getIntPointer(),10);
t.printP1(); //this fails.. but why? How can I fix it?
return 0;
}
The problem is that you initialize ip and you fill p1
void initializeP1(int **ip,int n){
sizeP1=n;
*ip=new int[n];
for(int i=0;i<n;i++)
*ip[i]=i;
}
//call with p1
initializeP1(&p1, 10); // pass pointer to pointer so you can get return value.
The problem is that your function allocates memory to the copy of the pointer that is the argument - this copy is lost at function exit. Pass the pointer by reference instead by changing the function signature
void initializeP1(int* &ip,int n){
^
This way the allocated memory is still accessible and your pointer will point to it
Would it not simply be easier to change your initializeP1 function to something like:
int * initializeP1(int n)
{
sizeP1 = n;
p1 = new int[n];
for(int i = 0; i < n; ++i)
p1[i] = i;
return ip;
}
There are still problems with this however, such as the fact that you can call it repeatedly and cause big memory leaks.
It might be better to use a proper constructor for your class that does what initializeP1 did, like such:
Test(int n)
{
sizeP1 = n;
p1 = new int[n];
for(int i = 0; i < n; ++i)
p1[i] = i;
return ip;
}
Pointers are not passed by reference, no. Pointers are value types. You'd want to use a reference if you absolutely had to make it look like this, but it's an abuse of syntax and you should do it a different way instead.
The call to t.getIntPointer() returns a pointer that is not initialised to something sensible.
The call to initializeP1() is newing an array of ints.
But be careful, this allocated block of memory will not be freed until you tell it so by writing "delete [] p1;".

Is it compulsory to initialize pointers in C++?

Is it compulsory to initialize t in the following code, before assigning value to t? Is the code correct?
void swap(int *x, int *y)
{
int *t;
*t = *x;
*x = *y;
*y = *t;
}
You don't need pointer to begin with:
void swap(int *x,int *y)
{
int t; //not a pointer!
t=*x;
*x=*y;
*y=t;
}
int a = 10, b = 20;
swap( &a, &b); //<-----------note : Needed &
--
Or maybe, you want the following swap function:
void swap(int & x,int & y) //parameters are references now!
{
int t; //not a pointer!
t=x;
x=y;
y=t;
}
int a = 10, b = 20;
swap(a,b); //<----------- Note: Not needed & anymore!
is the following section of code correct?
Nopes! Your code invokes Undefined behaviour because you are trying to dereference a wild pointer.
int *t;
*t=*x; // bad
Try this rather
int t; // a pointer is not needed here
t=*x;
or this
int *t = x; // initialize the pointer
That code contains undefined behavior:
int *t;
*t=*x; // where will the value be copied?
Besides that it makes no sense - you need a temporary variable to store the value, not the pointer.
int t; // not a pointer
t=*x;
*x=*y;
*y=t;
It's correct for a pointer.
Only references need to be initialized upon declaration (or in a constructor for instance members).
EDIT: but you got errors in your code, you shouldn't be dereferencing your parameters (ie int *ptr = otherPtr; is fine, not int *ptr = *otherPtr;)
If you just want to make your pointer point to already-initialized data, then you don't need to initialize it. The way you do it, though, yes, you want to use one of the malloc functions to allocate enough heap space for an integer.
The proper, efficient way, to do swapping in C/C++ is
void swap(int *x, int *y) {
int *t = x;
x = y;
y = t;
}
You can find the right way of doing this here
#include <stdio.h>
void swap(int *i, int *j)
{
int t;
t = *i;
*i = *j;
*j = t;
}
Basically the reason has been explained to you by sharptooth but there you will find some more details and explanations about what happens in background when you do such a swap. Hope it helps to clear your ideas.
int *t;
*t=*x;
t is not pointing to any valid location to be able to dereference.
is it compulsory to initialize , before assigning value to pointer t.
Yes, initializing / assigning to point to a valid memory location. Else where would it point to. It might some point to garbage and lead to undefined behavior on dereferencing.