为什么C函数没有char ** param设置char [] arg指针的值

时间:2013-06-30 17:04:02

标签: c

我的源文件有一个函数,我在对通过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;
}

我称之为

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

其中

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

服务器发送数据正常,它甚至在上面的函数中正确解析,但我似乎无法在我的struct的String变量中设置它。 在看到this之后我改变了我的功能以使用char ** param,但是当我打印时仍然变得垃圾

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

简而言之,我传递一个指向字符串的指针(&amp; myStructVar-&gt; szrecordid),使用malloc并通过charcter指定我的指针角色(后一部分来自link)。 在我将代码从使用char *更改为使用char **之前和之后我得到了相同的错误和编译器警告:

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

那么我做错了什么?

3 个答案:

答案 0 :(得分:4)

问题是指向数组的指针与指针指针不兼容。他们是不同的东西。这也是一件好事,因为这是为了捕捉代码中的错误。你在做什么基本上是这样的:

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

你应该能够看到问题;你正试图分配一个指向数组的指针。

答案 1 :(得分:1)

如果我理解正确,您的问题是您无法更改szrecordid的地址:

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

如果你不能改变这个变量的地址,那是因为它是一个数组。尝试使用char *而不是malloc并使用strcpy代替。

顺便提一下,请考虑尽可能使用strcpystrdup。基本上,你的功能正在做:

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

你还可以注意到第一个strcpy也没用。我不明白这个中间字符数组的含义。

答案 2 :(得分:1)

szrecordid是一个无符号字符数组,而不是指针,所以当你获取它的地址(&myStructVar->szrecordid)时,你得到一个指向数组的指针(unsigned char (*)[28]),而不是指向指针的指针,这是函数所期望的。

如果你考虑一下,那就很有意义了 - 你不能通过简单地改变它的地址来移动一个数组,因为它的地址(和大小)在它被分配时是固定的(当你创造它的任何东西时)那个myStructVar指向)。如果要更改该数组,则需要通过复制到其中来更改其内容,并且不会更改大小,该大小固定为28。

您问题的明显解决方案是将其设为指针而不是数组:

typedef struct _MY_STRUCT_TYPE {
    unsigned char   *szrecordid;
}