简体   繁体   English

为什么C函数不使用char **参数设置指向char [] arg的指针的值

[英]Why doesn't C function with char** param set value of a pointer to char[] arg

My source file has a function, which I invoke in the process of de-serializing a struct passed over a C socket (this is the client source): 我的源文件具有一个函数,该函数在对通过C套接字传递的结构进行反序列化的过程中调用(这是客户端源代码):

MY_STRUCT_TYPE myStructVar;

unsigned char * deserialize_chararr(unsigned char *buffer, unsigned char** value)
{
    unsigned char val[256];
    int i;
    for(i = 0; buffer[i]; i++) {
        val[i] = buffer[i];
    }
    val[i++] = '\0';
    printf("\n chararr: %s :", val);

    *value = malloc(i * sizeof **value);
    for(i = 0; buffer[i]; i++) {
        (*value)[i] = buffer[i];
        printf("%c", (*value)[i]);
    }
    (*value)[i++] = '\0';
    /* buffer contains a serialized struct read over a socket using recv. 
so this call returns the buffer pointer that get's passed to the next deserialize_<type> invocation a la https://stackoverflow.com/a/1577174/434145
That's why the first string extraction followed by an attempt to set it in the struct as part of unpacking. */
    return buffer + i;
}

that I'm calling as 我称之为

buffer = deserialize_chararr(buffer, &myStructVar->szrecordid);

where 哪里

typedef struct _MY_STRUCT_TYPE {
    unsigned char   szrecordid[28];
}

The server sends the data alright and it even parses correctly in the above function, but I can't seem to be able to set it in the String variable of my struct. 服务器发送的数据还不错,甚至可以在上述函数中正确解析,但是我似乎无法在结构的String变量中进行设置。 I changed my function to use char ** param after seeing this , but still get rubbish when I print 看到此信息后 ,我将功能更改为使用char ** param,但打印时仍会出现垃圾

printf("\n Payload:"  "\n szrecordid: %s ", myStructVar.szrecordid);

In short, I pass a pointer to a string (&myStructVar->szrecordid), use malloc and assign my pointee character by charcter (this latter part I got from the link ). 简而言之,我传递了一个指向字符串的指针(&myStructVar-> szrecordid),使用malloc并通过charcter分配了我的pointe字符(这是我从链接中获得的)。 Both before and after I changed the code from using a char * to using a char ** I was getting the same error and a compiler warning: 在将代码从使用char *更改为使用char **之前和之后,我都得到相同的错误和编译器警告:

client.c:159: warning: passing arg 2 of `deserialize_chararr' from incompatible pointer type

So what am I doing wrong? 那我在做什么错?

The problem is that a pointer to an array is not compatible with a pointer to a pointer. 问题是指向数组的指针与指向指针的指针不兼容。 They are different things. 他们是不同的东西。 And it's a good thing too, because this is meant to catch errors like the one in your code. 这也是一件好事,因为这是为了捕获代码中的错误。 What you are doing is basically this: 您在做什么基本上是这样的:

unsigned char szrecordid[28];
szrecordid = malloc(i * sizeof **value);

You should be able to see the problem; 您应该能够看到问题所在; you're trying to assign a pointer to an array. 您正在尝试将指针分配给数组。

If I understand correctly, your problem is that you can't change the address of szrecordid: 如果我理解正确,那么您的问题是您无法更改szrecordid的地址:

typedef struct _MY_STRUCT_TYPE {
    unsigned char   szrecordid[28];
}

And if you can't change the address of this variable it's because it's an array. 而且,如果您不能更改此变量的地址,那是因为它是一个数组。 Try using a char * instead or don't malloc and use strcpy instead. 尝试使用char *代替,或者不要malloc,而使用strcpy

By the way, please consider using strcpy and strdup when you can. 顺便说一句,请考虑strdup使用strcpystrdup Basically, your function is doing: 基本上,您的函数正在执行:

strcpy(val, buffer);
printf("\n chararr: %s :", val);
*value = strdup(buffer);
printf("%s", value);

And you could also notice that the first strcpy is useless too. 您可能还会注意到,第一个strcpy也没有用。 I don't understand the meaning of this intermediate char array. 我不明白这个中间字符数组的含义。

szrecordid is an array of unsigned characters, not a pointer, so when you taks its address ( &myStructVar->szrecordid ) you get a pointer to an array (an unsigned char (*)[28] ), and not a pointer to a pointer, which is what the function expects. szrecordid是一个无符号字符数组,而不是一个指针,因此当您查询其地址( &myStructVar->szrecordid )时,您将获得一个指向数组的指针(一个unsigned char (*)[28] ),而不是一个指向指针的指针,这是该功能所期望的。

If you think about it, it makes perfect sense -- you can't move an array by simply changing its address, as its address (and size) is fixed at the time it is allocated (when you create whatever it is that myStructVar points at). 如果您考虑一下,它就非常有意义-您不能仅通过更改其地址来移动数组,因为其地址(和大小)在分配时是固定的(当创建myStructVar指向的内容时在)。 If you want to change that array, you need to change its contents by copying into into it, and that won't change the size, which is fixed at 28. 如果要更改该数组,则需要通过将其复制到其中来更改其内容,并且不会更改其大小,该大小固定为28。

The obvious solution to your problem is make it a pointer instead of an array: 解决您的问题的明显方法是使它成为指针而不是数组:

typedef struct _MY_STRUCT_TYPE {
    unsigned char   *szrecordid;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM