uninitialized local variable

Pages: 12
lets say I have a text file which contains a mesh properties. I define a class named Mesh which reads the file and gives me the information which I named it Global Mesh. Then I am supposed to use MPI. I define another variable Mesh
*Local_Mesh and at the beginning I don't know what will be inside Local_Mesh.so I can't initialize it. and it gives me the error "uninitialized local variable".
how can I solve this?

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#include <assert.h>
#include <math.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <time.h>
#include <cstdlib> 
#include <stdio.h>
#include <mpi.h> 
#include <vector> 
#include<iterator>
#include<sstream>
#include<string>
#include<cmath>
#include<algorithm>
#include<iomanip>

#include "includes.h"
#include "typedefs.h"
#include "mesh.h"
#include "node.h"
#include "element.h"
#include "mpi_call.h"


typedef std::vector<Node>		VecNode_t; /*vector of number of Nodes*/
typedef std::vector<Element>	VecElm_t;  /*vector of number of Elements*/

int main(int argc, char *argv[])
{

	int num_procs, myrank;
	MPI_Init(&argc, &argv);
	MPI_Status status;
	MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
	MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

	if (myrank== 0) {
		Mesh* Local_Mesh;
		/*********************start reading mesh************************/
		/***************************************************************/
		size_t Nnodes;
		size_t Nelms;
		VecVecDbl_t Coordinates;
		VecVecIdx_t Connectivities;

		Mesh Global_Mesh;
		Global_Mesh.Mesh_Connectivity("mesh.txt");
		Global_Mesh.Mesh_Coordinate("mesh.txt");
		size_t Nelms_ = Global_Mesh.Nelms_;
		size_t Nnodes_ = Global_Mesh.Nnodes_;
		VecVecIdx_t Connectivities_ = Global_Mesh.Connectivities_;
		VecVecDbl_t Coordinates_ = Global_Mesh.Coordinates_;

		std::cout << "Printing Coordinates" << std::endl;
		std::cout << std::endl;
		for (size_t i = 0; i < Coordinates_.size(); i++) {
			for (size_t j = 0; j < Coordinates_[i].size(); j++) {

				std::cout << Coordinates_[i][j] << " ";
			}
			std::cout << std::endl;
		}

		std::cout << "Printing Connectivities" << std::endl;
		std::cout << std::endl;

		for (size_t i = 0; i < Connectivities_.size(); i++) {
			for (size_t j = 0; j < Connectivities_[i].size(); j++) {

				std::cout << Connectivities_[i][j] << " ";
			}
			std::cout << std::endl;
		}

		/************************end reading mesh*************************/
		/*****************************************************************/

		VecVecIdx_t MPI_Elms;
		{
			size_t Nelm = Global_Mesh.Connectivities_.size();
			//size_t res = Nelm % num_procs;
			size_t size = Nelm / num_procs;
			size_t res = Nelm - size * num_procs;

			MPI_Elms.resize(num_procs);
			size_t n_aux = 0;
			for (int i_proc = 0; i_proc < num_procs; i_proc++) {
				if (i_proc < res) {
					MPI_Elms[i_proc].resize(size + 1);
					for (int j = 0; j < size + 1; j++) {
						MPI_Elms[i_proc][j] = n_aux + j;
					}
					n_aux += size + 1;
				}
				else {
					MPI_Elms[i_proc].resize(size);
					for (int j = 0; j < size; j++) {
						MPI_Elms[i_proc][j] = n_aux + j;
					}
					n_aux += size;
				}
			}
		}

		VecVecVecIdx_t Local_Connectivities;
		VecVecIdx_t connect;
		for (int i_proc = 0; i_proc < num_procs; i_proc++) {

			for (int i_elm = 0; i_elm < MPI_Elms[i_proc].size(); i_elm++) {

				VecIdx_t elm_connect = Global_Mesh.Connectivities_[i_elm];
				connect.push_back(elm_connect);
			}
			Local_Connectivities.push_back(connect);
		}

		for (int i_proc = 0; i_proc < num_procs; i_proc++) {


			VecVecDbl_t Coordinates = Global_Mesh.Coordinates_;
			VecVecIdx_t Connectivities = Local_Connectivities[i_proc];

			size_t Nnodes = Coordinates.size();
			size_t Nelms = Connectivities.size();

			(*Local_Mesh).Mesh_build(Nnodes, Nelms, Coordinates, Connectivities);
			MPI_CALL call_mpisend;
			if (i_proc == 0) {

				call_mpisend.Send_to(i_proc,  Coordinates[i_proc]);
				//call_mpisend.Send_to(i_proc, Connectivities[i_proc]);
			}
			else
			{
				size_t Nnodes;
				size_t Nelms;
				VecVecDbl_t Coordinates;
				VecVecIdx_t Connectivities;

				MPI_CALL call_mpireceive;

				//call_mpireceive.Receive_from(0, Connectivities[i_proc]);
				call_mpireceive.Receive_from(0, Coordinates[i_proc]);
			}
		}
		
		VecNode_t Nodes;
		for (size_t i_node = 0; i_node < (*Local_Mesh).Nnodes_; i_node++) {
			VecDbl_t coord = (*Local_Mesh).Coordinates_[i_node];
			Node node(&coord);
			Nodes.push_back(node);
		}

		VecElm_t Elements;
		for (size_t i_elm = 0; i_elm < (*Local_Mesh).Nelms_; i_elm++) {
			VecIdx_t connect = (*Local_Mesh).Connectivities_[i_elm];
			Element elm(&connect, Nodes);
			Elements.push_back(elm);
		}

		MPI_Finalize();
		return 0;
	}
}

 
Last edited on
It's not just that you don't initialise it. Nowhere in your code do you ever give it any value at all.

What is is supposed to be? When do you ever expect to be able to give it a value, so that it can be used?
Local_Mesh is a pointer so can set it to nullptr.
However it seems that you don't use it, so you can comment it out and if your code compiles then remove it.
in line 127 it's going to have all values it needs
in line 127 it's going to have all values it needs

No. On line 127, you still haven't given Local_Mesh a value. It is uninitialised, so it contains an unknown value. Which means that when you dereference it - as you do on line 127 - you have undefined behaviour, because you're dereferencing an unknown value.

I'm not asking when you set values in an object that Local_Mesh might be pointing to. I'm asking when you intend to set the value of the pointer Local_Mesh itself.
What the heck is MPI_CALL?
MPI_CaLL is a user defined class for send and receive data.
@MikeuBoy
Why are you saying I'm not giving any value to *Loval_Mesh at line 127?
the function mesh build is doing that. I want to set the value for Local_Mesh when I obtain the Local_Connectivity

Last edited on
Why are you saying I'm not giving any value to *Loval_Mesh at line 127?

I haven't said that. I'm saying that you haven't given any value to Local_Mesh. Do you understand the difference?

the function mesh build is doing that

No it isn't. It is giving values to an object that Local_Mesh might be pointing to; that is, it is giving values to the object obtained by dereferencing Local_Mesh. But you haven't actually set Local_Mesh to point to anything, so when you dereference it, you're attempting to access a bit of memory at a random address, that hasn't been allocated, and hasn't been initialised as a Mesh object.

Do you understand that Local_Mesh is a pointer, not a Mesh object?

Do you understand what pointers are, and how they work?
Last edited on
The Local_Mesh is a pointer which point to the objects of Mesh class. I think I understand what pointer does. in this code I can't set any value for Local_Mesh before to point to before obtaining Local_Connectivity. So we arrive to my first question again. Can I write something like
*Local_Mesh=new Mesh...
Last edited on
The Local_Mesh is a pointer which point to the objects of Mesh class.

Right. And in your code, you don't set it to point to any such objects, anywhere. In fact, there is only one Mesh object anywhere in your code, Global_Mesh.

I can't set any value for Local_Mesh before to point to before obtaining Local_Connectivity

I can't see anything in your code called Local_Connectivity.

Can I write something like
*Local_Mesh=new Mesh...

Yes, of course. You create a Mesh object just like any other object.

Last edited on
VecVecIdx_t Connectivities = Local_Connectivities[i_proc];
I meant this line.

and when I write *Local_Mesh=new Mesh[num_procs] it gives me this error

fatal error LNK1120: 1 unresolved externals
Is there any reason why you thought it would be a good idea to withold the useful information from that error message, and only show us part of it? What did you think you would achieve by keeping part of the message secret from us?
Last edited on
I did not think anything.

error LNK2019: unresolved external symbol "public: __thiscall MPI_CALL::MPI_CALL(void)" (??0MPI_CALL@@QAE@XZ) referenced in function _main
1>E:\finite element class\Finite_element_csr_MPI\Debug\mpi.exe : fatal error LNK1120: 1 unresolved externals
1>Done building project "mpi.vcxproj" -- FAILED.
Your linker cannot find the definition of a default constructor for MPI_CALL.

Since you haven't shown us the definition of MPI_CALL, it's hard to comment further. You said the class was "user-defined" - does that mean you wrote it? If so, presumably you already know whether or not it has a default constructor?
1
2
3
4
5
6
7
8
9
10
11
class MPI_CALL {

public: 
	size_t sendto;
	size_t receive;
	VecDbl_t & Vector;

	MPI_CALL();
	void Send_to(size_t sendto, VecDbl_t & Vector);
	void Receive_from(size_t receivefrom, VecDbl_t & Vector);
};



and in the mpi_call.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "mpi_call.h"
#include "includes.h"
#include "typedefs.h"

void MPI_CALL::Send_to(size_t sendto, VecDbl_t & Vector)
{
	size_t Vector_size = Vector.size();
	double *Vector_pointer = &Vector[0];
	MPI_Send(Vector_pointer, Vector_size, MPI_DOUBLE , sendto, 0 , MPI_COMM_WORLD);
}


void MPI_CALL::Receive_from(size_t receivefrom, VecDbl_t & Vector)
{
	size_t Vector_size = Vector.size();
	double *Vector_pointer = &Vector[0];
	MPI_Status status;
	MPI_Recv(Vector_pointer, Vector_size, MPI_DOUBLE , receivefrom, 0, MPI_COMM_WORLD,&status);
}
Last edited on
.h line 8, you declare a default constructor.

As MikeyBoy said, there is no definition of your default constructor in your .cpp file.
in the .h file I can write MPI_CALL()=default;
But this time I get another error
When I call MPI_CALL call_mpisend, it says 'MPI_CALL::MPI_CALL(void)': attempting to reference a deleted function
Because you have a reference to Vector you cannot have a default constructor.
if I don't have any default constructor again I will get the same error
Pages: 12