Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么结构的这个内存副本没有按预期将字节复制到字节流?_C_Pointers_Memory - Fatal编程技术网

C 为什么结构的这个内存副本没有按预期将字节复制到字节流?

C 为什么结构的这个内存副本没有按预期将字节复制到字节流?,c,pointers,memory,C,Pointers,Memory,我需要序列化一个结构,我正在尝试使用memcpy来实现这一点。但它不起作用。我可以通过查看字节流来判断-我看到了垃圾字符。为什么? 我还得到运行时错误: 运行时检查失败#2-变量“addresses”周围的堆栈已损坏 发生了什么,我如何解决 我使用的是#pragma-pack(push,1),我认为这意味着不会对结构进行填充 #include <stdio.h> #include <string.h> #include <stdint.h> #pragma

我需要序列化一个结构,我正在尝试使用memcpy来实现这一点。但它不起作用。我可以通过查看字节流来判断-我看到了垃圾字符。为什么?

我还得到运行时错误:

运行时检查失败#2-变量“addresses”周围的堆栈已损坏

发生了什么,我如何解决

我使用的是
#pragma-pack(push,1)
,我认为这意味着不会对结构进行填充

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

#pragma pack(push, 1)  /* padding has to be disabled for casting to struct to work at other end */
typedef struct {
    uint8_t             start_char; 
    uint8_t             msg_type;      
    uint8_t             length;     
} MSG_HEADER;

typedef struct {
    uint8_t         denomination[6];   
    uint8_t         path;    
    uint8_t         min_level; 
    uint16_t        max_level;     
    uint16_t        weight;    
    uint8_t         address;  
} CONFIG_DATA;

typedef struct {
    MSG_HEADER            header;
    uint8_t               clear_type;  
    CONFIG_DATA           config_data[12]; 
    uint8_t               system_algorithm; 
    uint8_t               max_transaction;   
} MSG_CONFIGURATION;
#pragma pack(pop) /* only affect this file */

typedef struct {
    unsigned char data[256];
    size_t length;
    int msg_type;
} TCHU_MESSAGE;

enum DRM_MESSAGE_TYPE { 
    CONFIG, CLEAR_COUNT, DISPENSE, CANCEL_TRANSACTION };

void TestCopy()
{
    MSG_CONFIGURATION config;

    config.clear_type = 0;  
    config.system_algorithm = 0;
    config.max_transaction = 17;

    const int NumItems = 12;
    const uint16_t maxLevel = 300;

    static const char* denoms[] = { "GB005A","GB005B","GB010A","GB010B",
        "GB020A","GB050A","GB050B","GB100A",
        "GB100B","GB200A", "EU100A", "EU100B" };

    const uint8_t addresses[] =     { 0, 0, 5, 5, 0, 7, 7, 8, 8, 9, 0, 0 };
    const uint8_t sorting_paths[] = { 5, 5, 4, 4, 5, 2, 2, 1, 1, 3, 0, 0 };

    for(int i = 0; i < NumItems; ++i) {
        memcpy(config.config_data[i].denomination, denoms[i], 6);
        config.config_data[i].address = addresses[i];
        config.config_data[i].path = sorting_paths[i];
        config.config_data[i].min_level = 3;
        config.config_data[i].max_level = maxLevel;
        config.config_data[i].weight = 1000;
    }

    config.header.start_char = 1;
    config.header.msg_type = 2;
    config.header.length = sizeof(MSG_CONFIGURATION);

    TCHU_MESSAGE tchu_msg = {0};

    // why does the memcpy not work?  How can I get it to work?
    memcpy(tchu_msg.data, &config+sizeof(MSG_HEADER), sizeof(MSG_CONFIGURATION) - sizeof(MSG_HEADER));

    printf("sizeof(MSG_HEADER) = %u\n", sizeof(MSG_HEADER));
    printf("sizeof(MSG_CONFIGURATION) = %u\n", sizeof(MSG_CONFIGURATION));

    // get garbage in copyconfig
    MSG_CONFIGURATION copyconfig;
    memcpy(&copyconfig+sizeof(MSG_HEADER), tchu_msg.data, sizeof(MSG_CONFIGURATION) - sizeof(MSG_HEADER));

    if(copyconfig.header.start_char != config.header.start_char)
    {
        // we get to here
        printf("mismatch between original and copy\n");
    }
}

int main() {

    TestCopy();

    // I also get Run-Time Check Failure #2 - Stack around the variable 'addresses' was corrupted.
    // when program ends
}
#包括
#包括
#包括
#pragma pack(push,1)/*必须禁用填充,才能在另一端工作*/
类型定义结构{
uint8\u t start\u char;
uint8消息类型;
uint8_t长度;
}MSG_头;
类型定义结构{
uint8_t面额[6];
uint8_t路径;
uint8最低水平;
uint16最大电平;
uint16 t重量;
uint8_t地址;
}配置数据;
类型定义结构{
消息头;
uint8_t clear_类型;
配置数据配置数据[12];
uint8_t系统_算法;
uint8最大交易量;
}MSG_配置;
#pragma pack(pop)/*仅影响此文件*/
类型定义结构{
无符号字符数据[256];
尺寸与长度;
int-msg_型;
}TCHU_信息;
枚举DRM_消息_类型{
配置、清除\u计数、分发、取消\u事务};
void TestCopy()
{
MSG_配置;
config.clear_type=0;
config.system_算法=0;
config.max_transaction=17;
常数int NumItems=12;
const uint16_t maxLevel=300;
静态常量字符*denoms[]={“GB005A”、“GB005B”、“GB010A”、“GB010B”,
“GB020A”、“GB050A”、“GB050B”、“GB100A”,
“GB100B”、“GB200A”、“EU100A”、“EU100B”};
常量地址[]={0,0,5,0,7,8,8,9,0,0};
常量排序路径[]={5,5,4,4,5,2,2,1,1,3,0,0};
对于(int i=0;i
我的编译器立即告诉我出了什么问题:

warning: '__builtin___memcpy_chk' will always overflow destination buffer [-Wbuiltin-memcpy-chk-size]
    memcpy(&copyconfig+sizeof(MSG_HEADER), tchu_msg.data, sizeof(MSG_CONFIGURATION) - sizeof(MSG_HEADER));
为什么呢?好,让我们看看目的地:

&copyconfig + sizeof(MSG_HEADER)
这意味着“获取
copyconfig
的地址,将其视为一个数组,并获取第N个对象,其中N是
sizeof(MSG\u HEADER)
。我想您认为它会添加N个字节,但实际上它会添加N个
MSG\u配置的实例。相反,请使用以下方法:

&copyconfig.header + 1
也就是说,“获取
copyconfig.header
的地址并转到它的后面。”

你也可以这样做:

(char*)&copyconfig + sizeof(MSG_HEADER)
因为一个
char
的大小是一个字节。或者,由于您的结构已打包:

&copyconfig.clear_type
因为这是您实际要复制到的第一个字节的地址


有关更多详细信息,请阅读:。

欢迎使用堆栈溢出!听起来您可能需要学习如何使用调试器逐步完成代码。有了一个好的调试器,您可以逐行执行程序,并查看程序偏离预期的位置。如果您要进行任何编程,这是一个必不可少的工具。进一步阅读:像这样偏移到结构中是明智的吗?成员的顺序是由C保证的吗?为了简单起见,您不能从MSG_配置中删除MSG_头并单独发送它们,并且避免像那样偏移到结构中。您知道什么是
&config+sizeof(MSG_头)
是吗?它通过
sizeof(MSG_HEADER)*sizeof(MSG_CONFIGURATION)
字节推进地址
&config
。我认为这不是您想要的。您不需要序列化,只需要重新解释。使用正确的位操作和移位序列化。C标准没有定义该杂注(或大多数其他杂注)的行为从逻辑上讲,它可能应该是
©config.clear\u type
,而不考虑打包编译器对win的警告。啊,是的,因为+3是3 MSG\u配置的增量。这在迭代数组时是有意义的,但在我的情况下不是。是的,下次我将检查地址。引号:
,但它实际上添加了N个MSG\u HEADE实例R
-为什么?代码上写着
MSG\u配置copyconfig;
那么它不是MSG\u配置的N个实例吗?@4386427:你说得对,我现在已经解决了。谢谢你指出错误。