Why Warning "Using uninitialized memory '*unique_counts'" and how fix it? - c++

I am trying to solve problem: Find all unique elements of a two-dimensional array of integers using the MPI Scatter function for array scattering.
How fix it?
Severity Code Description Project File Line Suppression State Detail Description
Warning C6001 Using uninitialized memory '*unique_counts'. ConsoleApplication15 C:\Users\netd3en\source\repos\ConsoleApplication15\ConsoleApplication15\ConsoleApplication15.cpp 29
#include <iostream>
#include <unordered_set>
#include <mpi.h>
int main(int argc, char* argv[]) {
int size, rank;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int arr[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
int* local_arr = new int[3];
MPI_Scatter(arr, 3, MPI_INT, local_arr, 3, MPI_INT, 0, MPI_COMM_WORLD);
std::unordered_set<int> unique_elements;
for (int i = 0; i < 3; i++) {
unique_elements.insert(local_arr[i]);
}
int* unique_counts = new int[size];
int local_unique_count = unique_elements.size();
MPI_Gather(&local_unique_count, 1, MPI_INT, unique_counts, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (rank == 0) {
std::unordered_set<int> all_unique_elements;
int offset = 0;
for (int i = 0; i < size; i++) {
for (int j = 0; j < unique_counts[i]; j++) {
all_unique_elements.insert(local_arr[offset + j]);
}
offset += unique_counts[i];
}
std::cout << "Unique elements:";
for (auto it = all_unique_elements.begin(); it != all_unique_elements.end(); it++) {
std::cout << " " << *it;
}
std::cout << std::endl;
}
MPI_Finalize();
return 0;
}

You don't initialize allocated int array pointed by unique_counts and MPI_Gather can fail (you don't check a returned value) and leave the array elements unchanged. Try
int* unique_counts = new int[size]{};
^^
Don't forget delete[] unique_counts;

Related

Seg fault while using MPI_Scatter

I have problem with MPI_Scatter. Dont know hot to use it and my current program crashes with seg fault when I launch.
I guess that the problem in parameters of MPI_Scatter, particularly in calling it with right operator (& or * or void), but I've tried almost every combination and nothing actually helped.
#include <iostream>
#include <stdio.h>
#include <mpi.h>
// k = 3, N = 12, 1,2,3, 4,5,6, 7,8,9, 10,11,12
int main(int argc, char **argv) {
int N, size, myrank;
int k;
std::cin >> N;
std::cin >> k;
int *mass = new int[N];
int *recv = new int[k];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
if (myrank == 0) {
std::cout << "get k and n \n";
for (int i = 0; i < N; ++i) {
mass[i] = i;
std::cout << i << " written\n";
}
}
MPI_Scatter(mass, k, MPI_INT, recv, k, MPI_INT, 0, MPI_COMM_WORLD);
int sum = 0;
std::cout << "myrank" << myrank << '\n';
for (int i = 0; i < k; ++i) {
std::cout << recv[i] << '\n';
}
MPI_Finalize();
return 0;
}
When I launch this code, it prints this:
N = 12
k = 3
get k and n
0 written
1 written
2 written
3 written
4 written
5 written
6 written
7 written
8 written
9 written
10 written
11 written
myrank0
0
1
2
myrank1
myrank3
myrank2
[1570583203.522390] [calc:32739:0] mpool.c:38 UCX WARN object 0x7fe1f08b2f60 was not returned to mpool mm_recv_desc
[1570583203.523214] [calc:32740:0] mpool.c:38 UCX WARN object 0x7f4643986f60 was not returned to mpool mm_recv_desc
[1570583203.524205] [calc:32741:0] mpool.c:38 UCX WARN object 0x7f22535d4f60 was not returned to mpool mm_recv_desc
MPI typically redirects stdout to rank 0, so N and k are not correctly set on the other ranks.
Here is a working version of your program
#include <iostream>
#include <cassert>
#include <stdio.h>
#include <mpi.h>
// k = 3, N = 12, 1,2,3, 4,5,6, 7,8,9, 10,11,12
int main(int argc, char **argv) {
int k, N, size, myrank;
int *mass;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
if (myrank == 0) {
std::cout << "get k and n \n";
std::cin >> N;
std::cin >> k;
assert (N >= k*size);
mass = new int[N];
for (int i = 0; i < N; ++i) {
mass[i] = i;
std::cout << i << " written\n";
}
}
MPI_Bcast(&k, 1, MPI_INT, 0, MPI_COMM_WORLD);
int *recv = new int[k];
MPI_Scatter(mass, k, MPI_INT, recv, k, MPI_INT, 0, MPI_COMM_WORLD);
int sum = 0;
std::cout << "myrank" << myrank << '\n';
for (int i = 0; i < k; ++i) {
std::cout << recv[i] << '\n';
}
MPI_Finalize();
return 0;
}

Reversing array but only one element is returning

I'm trying to reverse an array and I think the for loop is wrong but everyone I've shown it to doesn't see a problem.
#include <iostream>
void reverse() {
int temp;
const int size = 9;
int arr[size] = {1, 4, 10, 16, 34, 7, 8, 9, 11};
for (int i=0; i <size-1; i++){
for (int j=size-1; j>=0; j--){
arr[j]= temp;
arr[i] = temp;
}
}
for(int x= 0; x<size; x++){
std::cout<<arr[x]<< " ";
}
}
int main () {
reverse();
return 0;
}
I suggest you use an algorithm of the std, namely std::reverse. You don't have to invent an algorithm, that reverts an array.
Thus your code is reduced to
#include <iostream>
#include <array>
#include <algorithm>
void reverse() {
std::array<int, 9> arr{1, 4, 10, 16, 34, 7, 8, 9, 11};
std::reverse(arr.begin(), arr.end());
for (const auto& item : arr) {
std::cout << item << " ";
}
}
int main() {
reverse();
return 0;
}
Choosing proper container and algorithm form the standard library will significantly enhance the quality (in terms of bugs, readability, ...) and speed up you development. Furthermore, in most cases the runtime of your program will be shorter as well.
#include<iostream>
using namespace std;
void reverse() {
int temp;
const int size = 9;
int arr[size] = {1, 4, 10, 16, 34, 7, 8, 9, 11};
for (int i=0, j =size-1; i <j ; i++, j--)
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
for(int x= 0; x<size; x++){
std::cout<<arr[x]<< " ";
}
}
int main () {
reverse();
return 0;
}
The variable 'temp' in your code is not initialised.
// I think this is what you are trying to do.
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
This would be faster. You just traverse half of the array and switch the elements don't do n² traversion, this is definitely not needed here.
void reverse() {
const int size = 9;
int arr[size] = {1, 4, 10, 16, 34, 7, 8, 9, 11};
int back = size - 1;
int temp;
for( int i = 0; i < size / 2; ++i)
{
temp = arr[i];
arr[i] = arr[back];
arr[back--] = temp;
}
for( auto n : arr )
std::cout << n << " ";
std::cout << std::endl;
}
to your code:
void reverse() {
int temp;
const int size = 9;
int arr[size] = {1, 4, 10, 16, 34, 7, 8, 9, 11};
for (int i=0; i <size-1; i++){
for (int j=size-1; j>=0; j--){ // here every element is set to
// temp, but temp isn initialized so they are set to a random value.
// Try setting temp to 0 and look what happens your whole array should
// become 0.
arr[j]= temp;
arr[i] = temp;
}
}
for(int x= 0; x<size; x++){
std::cout<<arr[x]<< " ";
}
}
check this one to reverse ur array..
#include <iostream>
using namespace std;
void reverse() {
int temp;
const int size = 9;
int arr[size] = {1, 4, 10, 16, 34, 7, 8, 9, 11};
for (int i=8; i>=0; i--){
// cout<<arr[i]<< " ";
std::cout<<arr[i]<< " ";
}
}
int main () {
reverse();
return 0;
}

I am trying to print out a multidimensional array, but it prints out weird memory address?

As you can see, I am trying to print out a 2D array but it prints out weird memory addresses! any ideas ! i am new to c++!
#include <iostream>
#include <string>
#include <Windows.h>
#include <cstdlib>
#include <ctime>
void display(int array[2][10], int size);
void main() {
SetConsoleTitleA("Random Number generator!");
system("Color 3F");
int Daniel[2][10] = { {20, 32, 43, 2, 5, 4, 3, 2 ,4 ,33}, {23, 54, 2, 5,3,3,6,3,65,3} };
display(Daniel, 7);
}
void display(int array[2][10], int size) {
for (int i = 0; i < size; i++) {
std::cout << array[i] << std::endl;
Sleep(1000);
}
}
Your array Daniel is 2D array, so if you try to print array[i], it prints an adress. If you want to print the content of the array, you should do it like this:
void display(int array[2][10]) {
for (int i = 0; i < 2; i++) {
for(int j = 0; j < 10; j++)
std::cout << array[i][j] << std::endl;
}
Also, your main() function should return int instead of void, so change void main() to int main() and return 0; at the end of it.
Pass in the array and the number of rows and columns:
#include <iostream>
void displayArray(int a[][10], size_t numRows, size_t numColumns)
{
for (size_t i = 0; i < numRows; i++){
for (size_t j = 0; j < numColumns; j++){
std::cout << a[i][j] << ' ';
}
std::cout << std::endl;
}
}
int main(){
int Daniel[2][10] = { { 20, 32, 43, 2, 5, 4, 3, 2, 4, 33 }, { 23, 54, 2, 5, 3, 3, 6, 3, 65, 3 } };
displayArray(Daniel, 2, 10);
return 0;
}

Algorithm for deleting multiple array elements and shifting array

I have an array let's say with 5 items, if element[i] is less than 3 need to move element[i+1] in place of element[i].
int array[5] = {4, 2, 3, 5, 1};
int number = 3;
for (int i = 0; i < number; i++)
{
if (array[i] > number)
{
for (int j = 0; j < i - 1; j++)
{
array[j] = array[j + 1];
}
number = number - 1;
}
}
expected result is array = {2, 3, 1, anyNumber, anyNumber};
A O(n) working code for the above problem.. But as others pointed out in the comments.. You end up with an array that is using less space then allocated to it..
#include<stdio.h>
int main()
{
int arr[] = {4, 2, 3, 5, 1};
int* temp1 = arr;
int* temp2 = arr;
int i, n1 = 5, n2 = 5;
for(i = 0; i < n1; i++)
{
if(*temp2 >= 3)
{
*temp1 = *temp2;
temp1++;
temp2++;
}
else
{
n2--; //the number of elements left in the array is denoted by n2
temp2++;
}
}
}
Nested loops give you O(n2) complexity, and non-obvious code.
Better use std::remove_if:
int array[5] = {4, 2, 3, 5, 1};
int number = 3;
remove_if( begin( array ), end( array ), [=]( int x ) { return x>number; } );
Disclaimer: code untouched by compiler's hands.
Try this code. You should not decrease number at each step. Also, the second loop should start at i and stop at the end of array:
int array[5] = {4, 2, 3, 5, 1};
int number = 3;
for (int i = 0; i < number; i++)
{
if (array[i] > number)
{
for (int j = i; j < 5; j++)
{
array[j] = array[j + 1];
}
}
}
Here's a more compact and idiomatic (that's how I view it anyway) way to remove items from an array:
#include <iostream>
#include <algorithm>
#include <iterator>
int main()
{
int array[] = {4, 2, 3, 5, 1};
int* begin = array;
int* end = begin + sizeof(array)/sizeof(array[0]);
int number = 3;
end = std::remove_if(begin, end, [&number](int v) {return v > number;});
std::copy(begin, end, std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;
}
Just for comparison, here's a version using std::vector:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main()
{
std::vector<int> array = {4, 2, 3, 5, 1};
int number = 3;
auto end = std::remove_if(array.begin(), array.end(), [&number](int v) {return v > number;});
std::copy(array.begin(), end, std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;
}
As an alternative, if you want to keep your items, but denote what will be at some later time, "removed", the algorithm that can be used is stable_partition:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <functional>
int main()
{
int vValues[] = {4,2,3,5,1};
// partition the values on left and right. The left side will have values
// <= 3, and on right >3. The return value is the partition point.
int *p = std::stable_partition(vValues, vValues + 5,
std::bind2nd(std::less_equal<int>(), 3));
// display information
std::cout << "Partition is located at vValues[" << std::distance(vValues, p) << "]\n";
std::copy(vValues, vValues + 5, std::ostream_iterator<int>(std::cout, " "));
}
Output:
Partition is located at vValues[3]
2 3 1 4 5
You will see that 2,3,1 are on the left of partition p, and 4,5 are on the right of the partition p. So the "removed" items start at where p points to. The std::partition ensures the elements are still in their relative order when done.
I created my own example, hope this helps people as a reference:
// Removing an element from the array. Thus, shifting to the left.
void remove(){
int a[] = {1, 2, 3, 4, 5, 6};
int size = sizeof(a)/sizeof(int); // gives the size
for(int i = 0; i < size; i++){
cout << "Value: " << a[i] << endl;
}
int index = 2; // desired index to be removed
for(int i = 0; i < size; i++){
if(i == index){
for(int j = i; j < size; j++){
a[j] = a[j+1];
}
}
}
size--; // decrease the size of the array
cout << "\nTesting output: " << endl;
for(int i = 0; i < size; i++){
cout << "Value: " << a[i] << endl;
}
}
int main(){
remove();
return 0;
}

Linear Search returning array with indices value is found at

I attempted a program to return an array with the indicies of the array where a specific inputed value is found, but every run results in an error, which seems to be an infinite run time. The error seems to be occuring right after printing out the last of the indicies found.
Can anyone help?
(Side note: I've seen multiple pages about deleting pointers when done with them; should I be doing that here?)
Forgot to mention - I want the first slot of the returned array to save the size of the array, so that it can be accessed easily later on in the program
#include <iostream>
#include <vector>
using namespace std;
int* linearSearch(int* n, int k, int f) {
// Input: Index 0 Address ; Size of Array; Element to Search
// Output: Array of Found Indicies
vector <int> a;
int* b;
for(int i = 0; i < k; i++)
if(n[i] == f)
a.push_back(i);
*b = a.size();
for(int i = 0; i < a.size(); i++)
b[i + 1] = a[i];
return b;
}
int main() {
int c[10] = {4, 4, 6, 3, 7, 7, 3, 6, 2, 0};
int* k = linearSearch(&c[0], sizeof(c)/sizeof(int), 4);
for(int i = 0; i < k[0]; i++) {
cout << "Found at index: " << k[i + 1] << endl;
}
return 0;
}
int* b;
....
*b = a.size();
b has to be allocated. Try following:
int* b = new int[a.size() + 1];
b[0] = a.size();
I see what you meant. b will have magically length in first element. This was in Pascal/Delphi but not the case in C/C++.
You are writing to heap memory that you never claimed.
int* b;
This pointer, having never been initialized, points to an undefined memory address. Then when you use the indexing operator to assign your matches, you are writing to the subsequent bytes following the undefined memory address.
You need to allocate space for storing the results using the 'new[]' operator. Additionally, if you had correctly claimed the memory, you would be assigning the number of match results to the first element in the result array - something that doesn't seem to be your intention.
Take a look at dynamic memory allocation in C++ using the new [] operator.
If you use std::vector anyway, why not to use it where it is needed the most? Also if you not suppose to modify array by that pointer express that by const pointer:
std::vector<int> linearSearch(const int* n, int k, int f)
{
std::vector<int> res;
for(int i = 0; i < k; i++)
if(n[i] == f) res.push_back(i);
return res;
}
int main() {
int c[10] = {4, 4, 6, 3, 7, 7, 3, 6, 2, 0};
std::vector<int> k = linearSearch(&c[0], sizeof(c)/sizeof(int), 4);
for(int i = 0; i < k.size(); i++) {
cout << "Found at index: " << k[i] << endl;
}
return 0;
}
This is not perfect but this is much closer to a correct implementation and you should be able to take it further with some work:
#include <iostream>
#include <vector>
using namespace std;
std::vector<int> linearSearch(int* n, int k, int f)
{
vector <int> a;
for(int i = 0; i < k; i++)
{
if(n[i] == f)
{
a.push_back(i);
}
}
return a ;
}
int main() {
int c[10] = {4, 4, 6, 3, 7, 7, 3, 6, 2, 0};
std::vector<int> result = linearSearch(&c[0], sizeof(c)/sizeof(int), 4);
for(unsigned int i = 0; i < result.size(); i++)
{
cout << "Found at index: " << result[i + 1] << endl;
}
return 0;
}