1

I'm a having problem when trying to assign a pointer to array to another pointer to array, please could you tell me where is the problem in the code bellow :

void sort_strlen(char (*pt)[81]){

  char (*temp)[81];
  int i, j;

  for(i = 0; i < 10 && *(pt + i) != NULL; i++)
    for(j = i + 1; j < 10 && *(pt + j) != NULL; j++)
     if(strlen(*(pt + i)) < strlen(*(pt + j))){
       temp = *(pt + i);
       *(pt + i) = *(pt + j);
       *(pt + j) = temp;
     }

  for(i = 0; i < 10 && *(pt + i) != NULL; i++)
    puts(*(pt + i)); 

}

GCC return "assigning incompatible types" error when compiling to this function. The problem must be obvious but I'm just a newbie, I can't find the problem by myself.

3
  • The use of pointers to arrays is vanishingly rare in idiomatic C programming. What is your ultimate goal? Commented Jan 9, 2013 at 5:25
  • @CarlNorum Thanks, the function upward aims at sorting an array of strings by their length. After checking if the string stored at the address where *(pt + i) points to is bigger than the one just after (*(pt + j)), I would like to interchange the addresses where the two pointers point to. However, gcc doesn't accept it. I could only solve the problem by adding an array of pointer to char where I store the addresses of each string and then interchange the addresses inside that array. Is there a better way to do the job ? Commented Jan 9, 2013 at 9:33
  • Welcome to SO. In addition to pointing out the line that causes the error with a comment (as suggested by @JonathanWood), the best questions are the ones that have removed any code that are not needed to cause the error you are asking about. Even if the error happens on three lines, if it's the same error then narrowing to one instance is usually enough to fix the rest yourself. For more on this strategy, see: sscce.org Commented Jan 9, 2013 at 11:31

2 Answers 2

1

Is this the line that causes the error? Looks like it. (You should've indicated in your question.)

*(pt + j) = temp;

pt is of type char (*pt)[81] and temp is of the same type. But you dereference pt when you do *(pt + j). (* dereferences a pointer and instead refers to the variable the pointer points to.)

As a result, *(pt + j) is of type char[81]. And that's why it's an error to assign temp to it.

If you know what you're doing, you could get away with this by typecasting. But it appears this is not what you expect so I don't recommend that.

Sign up to request clarification or add additional context in comments.

3 Comments

Actually gcc return error message for each of the three assignments : read_string.c: In function ‘sort_strlen’: read_string.c:73:18: error: incompatible types when assigning to type ‘char[81]’ from type ‘char *’ read_string.c:74:18: error: incompatible types when assigning to type ‘char[81]’ from type ‘char *’
I solved the problem by creating an array of pointers. I wanted to sort the strings directly by changing their addresses inside the array. Does anybody knows if it possible ? What is the best way to do it ?
"As a result, *(pt + j) is of type char *" No, it's of type char[81]. It's converted to char* in many situations, but not in *(pt + j) = temp;.
0

It may be easier to see the problem if we rewrite the function using subscript notation instead of *(pt+i).

void sort_strlen(char (*pt)[81]){

  char (*temp)[81];
  int i, j;

  for(i = 0; i < 10 && pt[i] != NULL; i++)
    for(j = i + 1; j < 10 && pt[j] != NULL; j++)
     if(strlen(pt[i]) < strlen(pt[j])){
       temp = pt[i];
       pt[i] = pt[j];
       pt[j] = temp;
     }

  for(i = 0; i < 10 && pt[i] != NULL; i++)
    puts(pt[i]); 

}

So when you're trying to swap pt[i] and pt[j], first you try to assign a char* (to which the char[81] pt[i] is automatically converted here) to a char(*)[81] in the temp = pt[i]; line.

The type incompatibility should be clear here. But usually, that one's only a warning and "works as intended" because pt[i] is converted to the address of the first byte in that string, which also is the address of the array pt[i]. The warning would vanish if the type of the right hand side is adjusted by assigning &pt[i] or pt + i.

The errors are on the next lines. In the pt[i] = pt[j]; line, you try to assign a char* to a char[81], and in the pt[j] = temp; line, you try to assign a char(*)[81] to a char[81].

Arrays are not assignable, so writing

pt[i] = ...

is always an error. It is unfortunate that gcc reports that as

sort_strlen.c:13:18: error: incompatible types when assigning to type ‘char[81]’ from type ‘char *’
sort_strlen.c:14:18: error: incompatible types when assigning to type ‘char[81]’ from type ‘char (*)[81]’

and not the more immediately pointing to the root cause

sort_strlen.c:13:18: error: array type 'char [81]' is not assignable
       *(pt + i) = *(pt + j);
       ~~~~~~~~~ ^
sort_strlen.c:14:18: error: array type 'char [81]' is not assignable            
       *(pt + j) = temp;
       ~~~~~~~~~ ^

that clang emits. The "incompatible types" that gcc reports are principally unfixable since no type on the right hand side is compatible with an array type on the left hand side of an assignment.

I solved the problem by creating an array of pointers. I wanted to sort the strings directly by changing their addresses inside the array. Does anybody knows if it possible ? What is the best way to do it ?

That depends what you want to do. You can't change the addresses of the strings without moving the strings themselves around, you would do that for example with

char temp[81];
...
    strcpy(temp, pt[i]);
    strcpy(pt[i], pt[j]);
    strcpy(pt[j], temp);

If you don't want to move the strings around, you would indeed best create an array of pointers

char *strings[10];
for(int i = 0; i < 10; ++i) {
    strings[i] = pt[i];  // make it &pt[i][0] if you don't like the implicit conversion
}

and sort the strings array by string length:

char *temp;
...
    if (strlen(strings[i]) < strlen(strings[j])) {
        temp = strings[i];
        strings[i] = strings[j];
        strings[j] = temp;
    }

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.