Passing array as argument to std::thread - c++

I'm having difficulty passing an array of integers to a function using std::thread. It seems like thread doesn't like the array portion of it. What other way is there to pass an array to a threaded function?
#include <thread>
#include <ostream>
using namespace std;
void process(int start_holder[], int size){
for (int t = 0; t < size; t++){
cout << start_holder[t] << "\n";
}
}
int main (int argc, char *argv[]){
int size = 5;
int holder_list[size] = { 16, 2, 77, 40, 12071};
std::thread run_thread(process,holder_list,size);
//std::ref(list) doesnt work either
//nor does converting the list to std::string then passing by std::ref
run_thread.join();
}

Since you are using C++ start using std::vector or std::list instead of the c-style arrays. There are many other container types as well. If you want a fixed size array use std::array instead (since C++11).
These containers have functions to get the size so you do not need to send it through as a separate argument.
#include <thread>
#include <iostream>
#include <vector>
void process(std::vector<int> start_holder){
for(int t = 0; t < start_holder.size(); t++){
std::cout << start_holder[t] << "\n";
}
// Or the range based for
for(int t: start_holder) {
std::cout << t << "\n";
}
}
int main (int argc, char *argv[]){
std::vector<int> holder_list{ 16, 2, 77, 40, 12071};
std::thread run_thread(process, holder_list);
run_thread.join();
}

Make size constant:
#include <thread>
#include <iostream>
void process(int* start_holder, int size){
for (int t = 0; t < size; t++){
std::cout << start_holder[t] << "\n";
}
}
int main (int argc, char *argv[]){
static const int size = 5;
int holder_list[size] = { 16, 2, 77, 40, 12071};
std::thread run_thread(process, holder_list, size);
run_thread.join();
}
If size is variable, int arr[size] is not a standard C++. It is a variable array extension to the language as your compiler says in the error and is not compatible with int* aka int [].

Related

How do I make an int that is the length of an array in C++?

So basically I'm trying to write a method that returns two times the length of an array, but I cannot figure out how to make the length into an int so that it can be used. I have been trying to figure out the correct method to use since sizeof() returns the number of bytes, not the length of the array. What method should I be using and how can I fix this? Here is my code:
int main(int argc, const char * argv[]) {
int arr[] = {1,2,3,4,5};
cout << getLen(arr);
return 0;
}
int getLen( int *arr ){
int len = sizeof(arr);
return 2 * len;
}
I think this could be an XY problem. Ultimately if you want this kind of behaviour in C++ you should use an std::vector object. For example:
#include <iostream>
#include <vector> // Remember to include this
int getLen(std::vector<int> &vec) // Pass vec by reference rather than as a pointer
{
return static_cast<int>(vec.size()) * 2; // Use .size() to get the number of elements in vec
// ^^^ .size() returns a value of type size_t which is converted to an int using static_cast<int>
}
int main()
{
std::vector<int> vec = {1,2,3,4,5};
std::cout << getLen(vec);
return 0;
}
#include <iostream>
template<typename T,std::size_t n>
std::size_t get_new_len(T (&a)[n]) {
return n*2;
}
int main() {
int a[10] = {0};
std::cout << get_new_len(a) << "\n";
}
you can do it in this way, using template argument deduction.
output is 20
The result of sizeof(arr) is not the same in the main as in the function, i don't understand why , but it works like this :
int getLen(int *arr, int arrSize)
{
int len = arrSize / sizeof(int);
return len;
}
int main(int argc, const char * argv[])
{
int arr[] = { 1, 2, 3, 4, 5 };
cout << getLen(arr,sizeof(arr));
return 0;
}

Finding the smallest value in an array

So I'm having some trouble with something. I have to create a function that will find the smallest number in an array. I know of one way to do it, using an overkill amount of if/else if, which won't do any good if the array size changes. I know using a for loop should do the trick but I can't figure out how to write it. Any push in the right direction would be greatly appreciated.
#include <iostream>
using namespace std;
int findLowest(int[]);
int main()
{
int AR[5] = {4, 87, 1, -3, 78};
cout << findLowest(AR);
return 0;
}
int findLowest(int AR[])
{
return lowest;
}
If you can change the function signature and include a header file that specifies general limits, you could do the following, which reads through the array in one pass:
#include <climits>
...
/* assumes AR_size > 0 */
int findLowest(int AR[], int AR_size)
{
int lowest = INT_MAX;
for (i = 0; i < AR_size; ++i) {
lowest = (AR[i] < lowest) ? AR[i] : lowest;
}
return lowest;
}
template<size_t N>
int findLowest(int (&ar)[N])
{
return *std::min_element(std::begin(ar), std::end(ar));
}
Note the usage of a template to make sure we get the size information from the caller.
#include <iostream>
#include <cassert>
using namespace std;
int findLowest(int ar[], const int& SIZE)
{
assert(("Error: the size of the array is zero. Make sure that ", SIZE > 0));
int lowest = ar[0];
for(int i=0; i<SIZE;i++)
{
if(lowest > ar[i])
lowest = ar[i];
}
return lowest;
}
int main()
{
const int SIZE(5);
int AR[5] = {11, 12, 10, 14, 15};
cout << findLowest(AR,SIZE);
return 0;
}
Instead of defining your own function to find the smallest number in your array, why do you not use the standard std::min_element function to do it for you? Create a std::vector object from the array, and let the min_element function do the job for you.
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <vector>
#define ARRAY_SIZE 5
int main ( int argc, char **argv )
{
int ar [ ARRAY_SIZE ] = {4, 87, 1, -3, 78};
std::vector<int> arVector ( ar, ar + ARRAY_SIZE );
std::cout << *std::min_element ( arVector.begin ( ), arVector.end ( )) << std::endl;
return EXIT_SUCCESS;
}
Output:
-3

C++ the dynamic array and file reading don't work together

Such a code:
int _tmain(int argc, _TCHAR* argv[])
{
int *test = new int[];
ifstream f("ofile.txt");
for (int i=0,v; i<10; i++)
{
f>>v;
test[i]=1;
cout<<"\nv = "<<v<<", i = "<<i<<endl;
}
return 0;
}
caused of this message after compiling:
I guess (correct me if I'm wrong) here is some error about memory, but details are unknown for me. If I remove one of them (file reading or array) it works.
So it will be great to hear an explanation of the problem.
You're thinking java. To allocate an array like that you need to give a size.
e.g.
int *test = new int[20];
However a better scheme would be to use a vector of integers.
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm> // for sort()
int main(int argc, char *argv[])
{
std::vector<int> data;
std::ifstream fsin("ofile.txt");
int count = 0;
while (fsin.good())
{
int v;
fsin >> v;
if (fsin.good())
{
data.push_back(v);
std::cout << "\nv = " << v << ", i = " << count++ << std::endl;
}
}
std::sort(data.begin(), data.end());
for (size_t i=0; i<data.size(); i++)
std::cout << i << '\t' << data[i] << std::endl;
return 0;
}
You have to allocate a fixed size array, int *test = new int[]; shouldn't even work.
If the size is known, use int *test = new int[size];, otherwise try using a std::vector or std:array.

Comparing two arrays and creating third array with common elements

I need to compare two arrays and output another array that shows common elements.
The output I'm expecting with my code is: 0000056789.
Help will be appreciated.
#include <iostream>
using namespace std;
const int CE = 10;
const int TOP = CE-1;
int iArr1[CE]={0,1,2,3,4,5,6,7,8,9};
int iArr2[CE]={5,6,7,8,9,10,11,12,13,14};
int iArr3[CE]={0,0,0,0,0,0,0,0,0,0};
void main()
{
int i;
int j;
int iCarr3 = 0;
for(i=0; i<=TOP; i++)
{
for (j=0; j<=TOP; j++)
{
if (iArr1[i]==iArr2[j])
{
iCarr3++;
iArr3[iCarr3]=iArr2[j];
}
}
}
cout << iCarr3 << endl;
cout << iArr3;
getchar();
}
you are printing the address of your array
to print the elements of an array
for (int i = 0; i < size; i++) // keep track of the size some how
cout<<iArr3[i]<<" ";
P.S: consider sorting the arrays first, and ckecking if iArr1[i] > iArr2[j]that way you won't need to scan all the elements on eavh pass
C++ has a set_intersection algorithm in the Standard Library:
#include <iostream>
#include <algorithm>
int main()
{
const int CE = 10;
int iArr1[CE] = {0,1,2,3,4,5,6,7,8,9};
int iArr2[CE] = {5,6,7,8,9,10,11,12,13,14};
int iArr3[CE] = {0,0,0,0,0,0,0,0,0,0};
std::set_intersection(std::begin(iArr1), std::end(iArr1),
std::begin(iArr2), std::end(iArr2),
std::begin(iArr3));
std::copy(std::begin(iArr3), std::end(iArr3), std::ostream_iterator<int>(std::cout, " "));
}
Output
5 6 7 8 9 0 0 0 0 0
Note
If your arrays aren't already sorted, you could put the data into a std::set first, since std::set_intersection() requires the inputs to be sorted.
Ok I hope this is not homework. The way you have it, the output will be 5678900000. For the output to be as you want change your code to be as such:
for(i=0; i<=TOP; i++)
{
for (j=0; j<=TOP; j++)
{
if (iArr1[i]==iArr2[j])
{
iArr3[iCarr3]=iArr2[j];
}
}
iCarr3++;
}
Then for the output do this:
for(int k = 0; k <= iCarr3; k++)
std::cout << iArr3[iCarr3] << " ";
As your array are sorted, use std::set_intersection. Otherwise you just have to std::sort them before.
But never forget to use the STD library, the code is a lot more compact and readable... And most of the time less buggy and faster that what you'll come with.
http://ideone.com/c3xE3m
#include <algorithm>
#include <iostream>
#include <iterator>
const size_t CE = 10;
int iArr1[CE]={0,1,2,3,4,5,6,7,8,9};
int iArr2[CE]={5,6,7,8,9,10,11,12,13,14};
int iArr3[CE]={0,0,0,0,0,0,0,0,0,0};
int main(int argc, char const *argv[])
{
auto end_elemnt =
std::set_intersection(iArr1, iArr1 + CE,
iArr2, iArr2 + CE,
iArr3);
std::copy(iArr3, end_elemnt, std::ostream_iterator<int>(std::cout, ", "));
return 0;
}
Here is the output:
$ ./a.exe
5, 6, 7, 8, 9,

C++ basic array assignment is not working

So I have a function
f(int D[],int A[],int len){
for(int k = 0; k < len; k++)
D[k] = A[k];
and if I output D the numbers are all wrong. The function f is called with D initialised as int* D = new int[100000]; in the main function and A is all good because I output it in the function and it looks ok. So... can't understand where the problem is... I also tried memcpy(D+k,A+k,sizeof(int)); and it doesn't work.
Your loop works perfectly. The problem must be somewhere else in your code.
Here is an example program which copies the data in three different ways: a for loop, memcpy, and std::copy:
#include <algorithm>
#include <cstring>
#include <iostream>
#include <iterator>
void copy1(int D[], int A[], int len) {
for(int k = 0; k < len; k++)
D[k] = A[k];
}
void copy2(int D[], int A[], int len) {
std::memcpy(D, A, len*sizeof(int));
}
void copy3(int D[], int A[], int len) {
std::copy(A, A+len, D);
}
int main () {
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int *d = new int[10];
std::ostream_iterator<int> out(std::cout, ",");
// First, print the initial values
std::copy(d, d+10, out);
std::cout << "\n";
// Next do the copies and print the values again
copy1(d, a, 10);
std::copy(d, d+10, out);
std::cout << "\n";
copy2(d, a, 10);
std::copy(d, d+10, out);
std::cout << "\n";
copy3(d, a, 10);
std::copy(d, d+10, out);
std::cout << "\n";
}
The output I get is:
0,0,0,0,0,0,0,0,0,0,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
Run your code in debugger and see if you do not have garbage in A[] in the first place (it could go wrong after function call). Also I suggest you pass reference (like int & D[] and const int & A[] — const to prevent altering of A).
Start with a minimal working example such as the following, then integrate your other code into it until something breaks. That’ll be the source of your error. Without more information, this is pretty much all I can tell you; when you encounter wrong values in a C++ program, you’re likely reading from an uninitialised variable. I suggest you try stepping through your program in a debugger such as GDB.
#include <algorithm>
#include <iostream>
#include <iterator>
void f(int D[], const int A[], int len){
for(int k = 0; k < len; k++)
D[k] = A[k];
}
int main(int argc, char** argv) {
int A[] = { 1, 2, 3, 4, 5 };
int D[5];
f(D, A, 5);
std::copy(A, A + 5, std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
std::copy(D, D + 5, std::ostream_iterator<int>(std::cout, " "));
return 0;
}
Unless you have a very good reason to do so, prefer std::vector and std::array over raw arrays. Learning how arrays and pointers work is a good reason to use them, though.
I believe the problem is that you are passing in a pointer to an array
int* D = new int[100000];
however, your function takes two integer arrays, which is not the same as a pointer to an array.
Here's a SSCCE of a snippet that behaves like you want it:
#include <iostream>
using namespace std;
void f(int * d, int * a, int length){
for(int k = 0; k < length; k++){
d[k] = a[k];
}
}
int main() {
int* a = new int[9];
for(int i = 0; i < 9; i++){a[i] = i;}
int* d = new int[9];
f(d, a, 9);
for(int i = 0; i < 9; i++){
cout << d[i] << " ";
}
}