In the topic Pointer Dereferences, we saw that there are techniques for dealing with incidental sharing of pointer-accessed storage in particular cases.
In general, to deal with sharing problems at indirect references you have to really understand what your program is doing. You cannot just do a text search for all the uses of a shared location and apply some transformation mechanically.
Although you may not know which memory location is being accessed by an indirect reference, you may be able to tell that a set of indirect references using the same pointer value implement an independent update pattern. The process for synchronizing independent updates of indirect references is the same as for variables. The only special concern is that you need to use the same lock for all data accesses that might be accessing the same memory locations. Using the same lock in more places means that your tasks will spend more time waiting for it.
Finally, your design may have tasks working on separate parts of a larger data structure. If you find sharing problems, it may be that the parts are not as independent as designed. In that case, you are likely to get the best results by disentangling the data structures to resolve the sharing problems.