0

When I print out my order[] array (or even the value of the previous index order[num-1]), every index is filled with the same value. Is this because when I pthread_join, I am changing all_png by reference and therefore when I set order[num] = all_png[0], when the value of all_png changes, so does every value of order[] which I had previously stored?

pthread_t *p_tids = malloc(sizeof(pthread_t) * 1);      
char *all_pngs[1] = {0};
int num;
char *order[50] = {0};
while(array_is_full(order) == 0){
//use thread to call CURL
          pthread_create(p_tids, NULL, get_png, NULL);
          pthread_join(p_tids[0], (void **)&(all_pngs[0]));
          //parse the png name and put it in the correct order
          sscanf(all_pngs[0], "%*[^0-9]%d", &num);
          if(order[num] == NULL){
          order[num] = all_pngs[0];
          printf("%s %s\n", order[num-1], order[num]);
 }

Also, array_is_full also works as supposed to and just checks if the array is still filled with 0's or not. If there are still 0's (not full yet) return 0.

The get_png method simply returns a void pointer to a char*. And fname is simply a char[] that holds the png file name (i.e. output_3.png). This function works as it's supposed to.

char *a = malloc(sizeof(char)*256);
a = fname;
return ((void *)a);

The output looks something like this.

(null) ./output_19.png
(null) ./output_16.png
(null) ./output_24.png
(null) ./output_21.png
(null) ./output_38.png
(null) ./output_5.png
(null) ./output_8.png
(null) ./output_7.png
(null) ./output_46.png
(null) ./output_43.png
(null) ./output_35.png
(null) ./output_11.png
(null) ./output_4.png
(null) ./output_48.png
./output_6.png ./output_6.png
./output_44.png ./output_44.png
./output_22.png ./output_22.png
./output_49.png ./output_49.png
(null) ./output_28.png
./output_47.png ./output_47.png
(null) ./output_26.png
(null) ./output_33.png
./output_17.png ./output_17.png
./output_18.png ./output_18.png
(null) ./output_32.png
(null) ./output_14.png
./output_45.png ./output_45.png
(null) ./output_42.png
./output_27.png ./output_27.png
./output_39.png ./output_39.png
(null) ./output_31.png
(null) ./output_30.png
./output_9.png ./output_9.png

As you can see the previous index of order is being updated to the current value of the current index even though I thought I was only setting order[num] not order[num-1] (which should have been set previously).

Why is this happening and is there a way to fix this?

Let me know if anything is unclear or if more code is needed. I am quite new to posting on here.

Thanks in advance!

Community
  • 1
  • 1
SteamedBun
  • 91
  • 9
  • 2
    There re some parts of code missing from your post for a fuller answer but, if you are trying to pass a whole array by value (i.e. *copy* all elements to the function) then you'll have to either make an explicit copy in the caller, or make the array a member (the only member) of a `struct` and pass that. – Adrian Mole Jun 08 '21 at 23:40
  • What parts should I include to make it more understandable? – SteamedBun Jun 08 '21 at 23:49
  • 3
    You should post code approaching something we can compile and test. – Adrian Mole Jun 08 '21 at 23:51
  • 2
    In particular, you should present a [mre] that demonstrates the problem. But this is not necessarily a question of "what parts". An appropriate MRE is sometimes derived from your original code, but usually not by just clipping out selected parts. Follow the link for more information. – John Bollinger Jun 08 '21 at 23:56
  • 1
    Anyway, my crystal ball tells me `get_png()` always returns *the same* pointer, so that assigning all those return values to various elements of `order` leaves them pointing to the same memory location, which will reflect the data most recently written there. – John Bollinger Jun 08 '21 at 23:59
  • @JohnBollinger Could you elaborate on that idea? I'm not quite sure what you mean though I think you may be right. How can I make it so that assigning various elements of order not point to the same memory location? Can I somehow, instead of pointing just, set the value equal to the return value from get_png(). Also, thanks I will look into MRE. – SteamedBun Jun 09 '21 at 00:06
  • 4
    @SteamedBun, it starts with presenting an MRE in the question. I'm not prepared to comment any further on code that I do not see. Note also that crafting a *bona fide* MRE is a useful debugging exercise in its own right. – John Bollinger Jun 09 '21 at 00:07
  • 1
    Also, `char *a = malloc(sizeof(char)*256);` followed by `a = fname;` is a definite code-smell. If you think that copies the string from `fname` to `a` then you're wrong - it replaces the pointer to the newly allocated memory, which can then no longer be accessed or freed. Use `strcpy` to copy the data. – Adrian Mole Jun 09 '21 at 00:20
  • @AdrianMole that completely solved the issue. Thanks so much! Could you possibly explain that last part of why it is wrong (for future reference). Trying to understand this, a is just a pointer to fname which gets deallocated after the method finishes? Or something like that? Thanks for the help btw. – SteamedBun Jun 09 '21 at 00:30
  • 1
    There are lots of posts on Stack Overflow explaining the difference between copying a `char*` pointer and copying the data that is pointed-to. [Here's one I made earlier](https://stackoverflow.com/a/60729550/10871073). – Adrian Mole Jun 09 '21 at 00:44

0 Answers0