double pointer vs pointer to array, incompatible pointer type

人盡茶涼 提交于 2020-07-03 07:25:34

问题


Having this:

#define _DEFAULT_SOURCE 1
#include <stdio.h>
#include <string.h>

int main(){
    char *token, org[] = "Cats,Dogs,Mice,,,Dwarves,Elves:High,Elves:Wood";
    while((token=strsep(&org,",")))
        printf("Token: %s\n",token);
}

gives err (incompatible pointer type):

/usr/include/string.h:439:14: note: expected ‘char ** restrict’ but argument is of type ‘char (*)[47]’
 extern char *strsep (char **__restrict __stringp,
  1. I know it is different type (one has memory initialized -> org[], but the function wants pointer without any memory initialized), but they have the same behaviour, so why it complain anyway?

  2. And can somone explain me, what is the meaning of this keyword restrict or __restrict in case of *strsep (char **__restrict __stringp, (on the other hand, I assume the __stringp is not a internal datatype (because of double underscores) but only a fancy variable name).

Edit: I think an array is stored in stack, but the strsep wants a pointer that points to a heap, which could be done with having org allocated with malloc and then memcpy, or even better, copy the string via strdup (which does internally memcpy). But anyway, way does strsep wants pointer that points to heap and not to stack? Both are just pointers, point only to different addresses, but that should not mind.


回答1:


The strsep function requires the address of a modifiable pointer as its first argument (or NULL, in which case it does nothing); you are passing it the (fixed) address of an array. You can fix this by declaring a separate char* variable and assigning to that the (address of the) org array:

int main()
{
    char* token, org[] = "Cats,Dogs,Mice,,,Dwarves,Elves:High,Elves:Wood";
    char* porg = org; // "porg" is a MODIFIABLE pointer initialized with the start address of the "org" array
    while ((token = strsep(&porg, ",")))
        printf("Token: %s\n", token);

    return 0;
}

From the Linux manual page (bolding mine):

If *stringp is NULL, the strsep() function returns NULL and does nothing else. Otherwise, this function finds the first token in the string *stringp, that is delimited by one of the bytes in the string delim. This token is terminated by overwriting the delimiter with a null byte ('\0'), and *stringp is updated to point past the token. In case no delimiter was found, the token is taken to be the entire string *stringp, and *stringp is made NULL.

On the meaning and use of the restrict keyword, maybe this will help: Realistic usage of the C99 'restrict' keyword?.




回答2:


Address of the array references the place where the array starts, it has only the different type - pointer to the array. It is not pointer to pointer.

    char *token, org[] = "Cats,Dogs,Mice,,,Dwarves,Elves:High,Elves:Wood";
    char *pointer = org;
    while((token=strsep(&pointer,",")))
    /* ... */

You cant cast reference to array to double pointer.

restrict it a quite advanced topic. It promises the compiler that if the object referenced by pointer is modified, the access to this object can be only done by this pointer. It helps the compiler in the code optimisations

Generally speaking I would not expect you to use this qualifier before you get proficient in the C language.




回答3:


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

int main()
{
    char org[] = "Cats,Dogs,Mice,,,Dwarves,Elves:High,Elves:Wood";
    char *token = strtok(org, ",");
    while (token != NULL) {
        printf("Token: %s\n", token);
        token = strtok(NULL, ",");
    }
}

I think you should take a look at this page : Restrict type qualifier



来源:https://stackoverflow.com/questions/62499657/double-pointer-vs-pointer-to-array-incompatible-pointer-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!