0

I have an array of pointers to arrays, in a function. I need to access that array in another function.

Pointer array

char *ptr[size + 1];

I made a global pointer

char *p;

which i pointed to ptr (in the same function as ptr)

p = *ptr;

then i tried to access ptr from the other function

void otherFunction(void){
    for(int n = 0; n < 6; n++)
    {
        char* str = &p[n];
        printf("%i %s\n", n, str);
    }
}

when

ptr[0] = "abcd"
ptr[1] = "bcde"
ptr[2] = "cdef"
ptr[3] = "defg"
ptr[4] = "efgh"
ptr[5] = "fghi"

the output of otherfunction(); is:

0 abcd
1 bcd
2 cd
3 d
4 
5 

I want the output to be

 0 abcd
 1 bcde
 2 cdef
 3 defg
 4 efgh
 5 fghi

My questions are: (0) whats going wrong here. (1) How do i fix it (2) Or is there a better way to do this. the requirements are otherfunction() cant take any arguments and ptr needs to remain local to its function. (Im certain the other code is not contributing to the problem and nothing is wrong with ptr)

8
  • 1
    p = *ptr; dereferences ptr and is identical to saying p = ptr[0]; Commented Jan 2, 2017 at 3:58
  • 1
    You know you can pass parameters, don't you? Commented Jan 2, 2017 at 3:59
  • 4
    it should be noted that global pointers are rarely a good idea, especially if you're going to point them to local variables. Once the function completes, the stack will be cleaned up and you then get undefined behavior. Commented Jan 2, 2017 at 4:00
  • 2
    @Goodies and that's just a simple scenario where this would be a bad idea, global pointers are bad almost for any situation. Besides, there is always a solution other than using global variables and they are always better solutions than using global variables, so I recommend to avoid global variables as much as possible even if it sounds too drastic. Of course this comment is mostly for the OP. Commented Jan 2, 2017 at 4:02
  • 1
    @Goodies p = ptr; would be an error Commented Jan 2, 2017 at 4:08

3 Answers 3

3

ptr is an array of pointer.

char **p = ptr;

char *str = p[n];
printf("%i %s\n", n, str);
Sign up to request clarification or add additional context in comments.

3 Comments

What is the use of p? Why not simply do char* str = ptr[n];?
@Lundin I don't know, ask to the OP. Maybe p is global but not ptr. This answer is just a quick answer not exhaustive, I already upvote the two other because of that.
That's kind of the point though. The OP most likely shouldn't have their "global pointer" to begin with.
2

char *ptr[size + 1];

char* p = *ptr;

char* str = &p[n];

This makes p point to the first string of the ptr array of strings, and then str will iterate over that string character by character. I think that what you meant to do is this:

char** p = ptr; // p points to the first string of ptr
...
char* str = p[n]; // str points to the nth string of ptr

Apart of that, using global pointers is not a good idea. Possibly better is to pass ptr itself to the function otherFunction, which would have the protoype:

void otherFunction(char** p);

and you call it with ptr:

otherFunction(ptr);

Comments

1

(0) whats going wrong here. (1) How do i fix it (2) Or is there a better way to do this

(0) The whole program design. Using global variables like this - pointers in particular - is one form of spaghetti programming and should be avoided. You are creating tight couplings and dependencies between all kinds of unrelated parts in your program.

In general, the presence of pointer-to-pointers is usually an indication of poor design. Pointer-to-pointers have a few valid uses, for special cases such as returning a modified pointer through a function parameter. There is no apparent reason to use them in your case.

(1) By using a couple of type qualifiers and storage specifiers to reduce scope of those messy, global variables. Instead, access the pointer array through setter/getter functions.

(2) Yes, change the program to something like the code below:

static const char* ptr [] =
{
  "abcd",
  "bcde",
  "cdef",
  "defg",
  "efgh",
  "fghi",
  NULL
};

inline const char* get_str (size_t index)
{
  return ptr[index];
}

inline void set_str (size_t index, const char* str)
{
  ptr[index] = str;
}

3 Comments

"In general, the presence of pointer-to-pointers is usually an indication of poor design.", so int main(int, char **); is a poor design? This is really strict. I totally agree with all your answer except that. 3 stars programmers must be punished, I agree but, two starts? There are many cases where they are valid.
@Stargateur char** argv is strictly speaking not a valid form of main, but of course char* argv[] decays into a pointer-to-pointer, so they are equivalent. The presence of two stars means that you are doing something out of the ordinary, like returning a pointer to malloc:ed data through a parameter - which is perfectly fine. Using pointer-to-pointer in other situations is in my experience most often the result of programmer confusion. For example incorrectly using char** ptr = malloc(n*sizeof(*ptr)), to allocate a "2D array".
It would however be fine to use pointer-to-pointer when allocating an array of pointers dynamically - though it would be more correct to use an array pointer in that case. Pointer-to-pointers are perfectly fine if you actually know what you are doing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.