tags:

views:

1123

answers:

3

When I try to compile the following code I receive an error: "Type error in argument 1 to 'allocate'; found 'char * *', expected 'char *" at the line indicated (<<<<<). Explanations would be appreciated.

#include <stdio.h>
#include <string.h>

void allocate(char *dt);

int  main(void)
{
  char *data[3];

  allocate(data); <<<<<
    return 0;
}

void allocate(char *dt)
{ 
  int i;
  char buf[] = "A test string";

  for (i = 0; i < 3; i++){
    strcpy(&dt[i], buf);
    printf("%s\n", dt[i]);
  }
}

My understanding is that I should call allocate thus: allocate(&data) but with this I receive the following error: "Type error in argument 1 to 'allocate'; found 'char * (*)[3]', expected 'char *'".

It should be obvious that I am trying to make the contents of *data[] == buf.

A: 

The problem is in the declaration of the variable data. You have specified both a pointer (*) and an array ([]). The actual type of data is an array of pointer values.

For the purpose of this particular overload, the array acts as another pointer so you have a char pointer pointer in data (char**). The function allocate is expecting a single pointer value.

You can fix this by eliminating the pointer portion of the data type declaration.

char data[3];
JaredPar
But then the strcpy and the for loop in allocate don't make any sense and are dangerous?
Charles Bailey
Jared: I am actually trying to populate an array of 3 pointers to char.Doesn't char data[3] mean an array of 3 chars?
@Charles, yes they are. The immediate question was why am I getting this message which I was attempting to cover.
JaredPar
Fair enough, I don't disagree with the explanation, I was just questioning the 'fix'.
Charles Bailey
A: 

Main is right. It's allocate that's wrong.

Simply change

void allocate(char *dt)

to

void allocate(char **dt)

or (equivalently)

void allocate(char *dt[])

The argument to allocate is logically "An array of strings", which is the same as "An array of char pointers" which (as far as an argument is concerned) is the same as "A pointer to a char pointer".

Tyler McHenry
Tyler: so how would I express the argument to allocate()?
+3  A: 

It looks like allocate is trying to allocate three strings dynamically and assign them to each member of an array of three char* pointers.

Arrays decay to pointers when you pass them as function arguments which is what you want, so the declaration of allocate needs to be void allocate(char**). Passing in data will pass in a pointer to the first element of the array, i.e. a pointer to a char*.

In allocate you will need to allocate some memory for the new strings. I'm presuming that as this is a test example you really do want separate copies of the strings for each member of the array.

Of course, at this point you will probably want a deallocate function and make sure that this is always called to perform the corresponding free for the new mallocs.

void allocate(char** dt)
{ 
    int i;
    size_t len;

    char buf[] = "A test string";
    len = sizeof buf;

    for (i = 0; i < 3; i++)
    {
        dt[i] = malloc(len);
        if (dt[i] != NULL)
        {
            memcpy(dt[i], buf, len);
            printf("%s\n", dt[i]);
        }
    }
}
Charles Bailey
Charles: thank you - that produces the required result.