Cast char *简称*

问题描述 投票:0回答:4

我想总结一下我结构的所有字节。我读到我应该将我的结构的指针从char转换为short。为什么?

使用(短)从char到short的铸造是否正确?

我的代码

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

struct pseudo_header
{
    int var1;
    int var2;
    char name[25];
};

void csum(const unsigned short* ptr, int nbytes)
{
    unsigned long sum = 0;

    for(int i = 0; i < sizeof(struct pseudo_header); i++)
    {
        printf("%#8x\n", ptr[i]);
        sum+= ptr[i];
    }

    printf("%#8x", sum);
}

int main() {

    struct pseudo_header psh = {0};
    char datagram[4096];

    psh.var1 = 10;
    psh.var2 = 20;

    strcpy(psh.name, "Test");

    memcpy(datagram, &psh, sizeof(struct pseudo_header));

    csum((unsigned short*)datagram, sizeof(struct pseudo_header));

    return 0;
}

看起来它有效,但我无法验证这一点。任何帮助表示赞赏。

c++ c
4个回答
3
投票

不,取消引用已设置为从char*short*的强制转换结果的指针的行为是未定义的,除非char*指向的数据最初是short对象或数组;你的不是。

用于分析内存的定义良好的方式(在C和C ++中)是使用unsigned char*,但要注意不要遍历内存以便到达不属于您的程序的区域。


1
投票

基本上这是有效的,因为你清除了零结构。 = {0}。 您可以为函数指定结构struct * pseudo_header的指针。

我会看到对齐问题。

如果我必须在结构之前添加一个pragma pack()语句,然后在函数内部转换为unsigned char *,我会检查sizeof(struct ..)的期望值33。

使用25个字符长度名称测试您的函数。


0
投票

short至少有两个字节。因此,如果你想总结所有字节,那么转换为short*是错误的。而是投向unsigned char*


0
投票

使用char *以外的任何类型对指针进行强制转换(别名)违反了严格别名规则。 Gcc将根据严格别名规则的假设进行优化,并可能导致有趣的错误。 Tge只有真正安全的方式绕过严格的别名规则是使用memcpy。 Gcc支持memcpy作为编译器内在函数,因此可以优化到副本中。

或者,您可以使用-fno-strict-aliasing标志禁用严格别名。

PS - 我不清楚联盟是否提供了一个合适的方法来绕过严格的别名规则。

© www.soinside.com 2019 - 2024. All rights reserved.