2

My aim is to have second_func print to screen both the size parameter and the first vector element contained in the struct passed to it from p_thread create. The issue is with printing the vector element. I have the following code:

#include <iostream>
#include <bits/stdc++.h>
#include <pthread.h>

using namespace std;
void first_func(vector<int>& vect);
void * second_func(void * args);

struct t_args {
   vector<int> *vect;
      int size;
   };

int main() {
   vector<int> vect;
   vect.push_back(100);
   first_func(vect);
   return 0;
}

void first_func(vector<int>& vect) {
   int record;                            
   pthread_t thread;                  
   struct t_args args;             
   args.vect = &vect;                   
   args.size = 5;                      
   record = pthread_create(&thread, NULL, &second_func, (void *)&args);
   if (record) { 
      cout << "Error - Not able to create thread." << record << endl;
      exit(-1);
    }
    pthread_join(thread, NULL);
}

void * second_func(void * args) {
   struct t_args params = *(struct t_args*) args;
   cout << "The value of the size param is " <<  params.size << endl;
   cout << "The value of the first element of the vector is " << params.vect[0] << endl;
   pthread_exit(NULL);
}

It causes the following error.

something.cpp: In function ‘void* second_func(void*)’:
something.cpp:38:63: error: no match for ‘operator<<’ (operand types are ‘std::basic_ostream<char>’ and ‘std::vector<int>’)
    cout << "The value of the first element of the vector is " << params.vect[0]

The full error message is quite long, but this is the gist of it. The program was compiled with the following command:

g++ file.cpp -std=c++11 -lpthread -o file

I am pretty sure this is an issue related to pointers and proper dereferencing syntax, however, after many attempts and altering the syntax, some form of the error persists.

HMLDude
  • 1,547
  • 7
  • 27
  • 47
  • 1
    Unrelated: Using `#include ` along with `#include ` suggests that you don't know what `#include ` does. I recommend against using stuff before you know what it does. You don't necessarily have to know the how, but the what is extremely important. In this case one of the things you should know about `#include ` [is never use it directly](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h). – user4581301 Sep 21 '19 at 00:04

2 Answers2

1
vector<int> *vect;

declares a pointer to a vector.

params.vect[0]

Will treat that pointer line an array and get you the first vector, not the first element of the pointed at vector.

params.vect[0][0]

to get the first vector and then the first element of that first vector or the significantly less misleading since there is only one vector

(*params.vect)[0]
 ^ dereference operator gets vector at pointer

Will get the element you want.

By the way, be very careful passing pointers to local variables into threads. This time you're safe since the local variable is scoped by main and if main exits, so does the program and the thread (usually. I haven't seen a case that runs POSIX where it doesn't (But apparently you can do it)). However if you call a function to spin up a thread and use a variable local to that function in the thread, odds are very good that by the time the thread runs the function has returned and the variable is out of scope. It's a real bad scene to use a variable when after it's gone out of scope.

user4581301
  • 33,082
  • 7
  • 33
  • 54
  • What if I wanted to change the value of the underlying vector at index 0. Could I say `(*params.vect)[0] = 2`? – HMLDude Sep 21 '19 at 00:23
  • 1
    Once you dereference the pointer, you can use it normally. Why not try running your line and see if it works? – ggorlen Sep 21 '19 at 00:25
  • The command `(*params.vect)[0]=2`, does in fact change the underlying vector's value. However, if I make a local variable, from inside the function, `vector vect = (*params.vect);` and then say `vect[0]=999', the underlying array's value at index 0 does not change. Which is a bit confusing. – HMLDude Sep 21 '19 at 00:57
  • 2
    `vector vect = (*params.vect);` copies `*params.vect` into the new local `vector`. Changing a copy doesn't do diddly to the source. But if you use a reference... `vector &vect = (*params.vect);` Now you're playing with the real mcCoy. – user4581301 Sep 21 '19 at 00:59
0

Your vect member is a pointer, so you need to dereference it before you can index into it:

cout << "The value of the first element of the vector is "
     << (*params.vect)[0] << endl;

Output:

The value of the range param is 5
The value of the first element of the vector is 100

As mentioned in the comments, avoid #include <bits/stdc++.h>, using namespace std; and pthreads (prefer std::thread). Beyond that, I'll assume that the example is contrived simply to determine how to access the vector (as is, the program doesn't really do much or require threading).

ggorlen
  • 44,755
  • 7
  • 76
  • 106