C 初始化数组时出现分段错误

C 初始化数组时出现分段错误,c,C,我有一个叫做字符串的结构 typedef struct { char *s; int len; } string_t; typedef struct { uint32_t numb; } msg_t; 在函数中的什么位置 void myfunct() { msg_t msg; memset(&msg, 0, sizeof(msg)); msg.numb = 1; char *ClientSendBuf[sizeof(msg)];

我有一个叫做字符串的结构

typedef struct {
    char *s;
    int len;
} string_t;


typedef struct {
    uint32_t                numb;
} msg_t;
在函数中的什么位置

void myfunct()
{
msg_t msg;
memset(&msg, 0, sizeof(msg));
msg.numb = 1;
char *ClientSendBuf[sizeof(msg)];
string_t buffer = {ClientSendBuf[sizeof(msg)],strlen(ClientSendBuf[sizeof(msg)])};
}
尝试使用UDP初始化数组(基本上是我稍后需要发送的缓冲区), 但它给了我一个分段错误(在void myfunct的第三行)。 所以缓冲区的问题是它应该是一种字符串类型,如何修复这个分段错误


另外,我忘了提到,我想用memcopy将整个结构复制到缓冲区变量(应该是string类型)。那么,我做了上述错误的事情吗?我该怎么做呢?

ClientSendBuf-在其中放入一些东西,并将其放在堆上。

我看到两件事是错误的。首先,访问
ClientSendBuf[sizeof(msg)]
是未定义的行为,因为该字符位于
CliendSendBuf
的末尾。当需要
char*
时,您将分配一个
char
(即
ClientSendBuf[sizeof(msg)]

如果要在该函数之外使用缓冲区,则必须将
ClientSendBuf
放在堆上,因为退出后它将被其他堆栈帧覆盖(即某种程度上被删除),因此指向的数据将被丢弃。
现在,由于您需要整个
ClientSendBuff
的副本,因此需要一个
string\u t
数组。然后,将
ClientSendBuff
中的每个指针分配给
缓冲区

char *ClientSendBuff[sizeof(msg)];
string_t buffer[sizeof(msg)];
int i;

for(i = 0; i < sizeof(msg); i++) {
    ClientSendBuff[i] = malloc(100); // you have to initialize (and free when
    buffer[i].s = ClientSendBuff[i]; // you don't need them anymore) every pointer
    buffer[i].len = 100;
}
char*ClientSendBuff[sizeof(msg)];
字符串缓冲区[sizeof(msg)];
int i;
对于(i=0;i

但是我不确定我是否明白你的意思。一个
char*[]<代码> > char *< /c> > 

问题是,您不分配内存到clitsEndof的任何元素。这里应该使用Maloc来首先分配内存。

在初始化结构时必须考虑的一些事情,因为它有一个指针成员<代码> char * 简单的赋值是行不通的。分配将只复制指针地址,而不是它所指向的内容。
您的作业代码中存在一些问题:
1.您使用
sizeof(msg)
元素声明了一个
char*
数组,其中没有一个是分配内存的;但是您的结构需要
char*
而不是
char*[]

2.您访问的数组元素超出了范围(
ClientSendBuf[sizeof(msg)]
),并且没有指向任何有效地址。
您可以创建一个简单的
char
数组并将其复制到结构中。当您使用指针成员时,分配内存和释放内存是您的责任。
希望下面的代码能为您提供一些参考:

void myfunct()
{
   msg_t msg;
   memset(&msg, 0, sizeof(msg));
   msg.numb = 1;
   char ClientSendBuf[] = "This is my message";

   string_t buffer = {
                     strdup(ClientSendBuf), /*Can return NULL so add error check*/
                     strlen(ClientSendBuf)
   };
    /** Or **/
    string_t buffer;
    buffer.s = malloc(strlen(ClientSendBuf)+1);
    if(NULL == buffer.s)
    {
      /* Memory allocation failed. Handle error.*/
    }
    /* Zero fill */ 
    memset(buffer.s, 0, strlen(ClientSendBuf)+1);
    strcpy(buffer.s, ClientSendBuf);
    buffer.len = strlen(ClientSendBuf);
     /*Opeartions with buffer*/
     /*Call free in both cases !*/
     free(buffer.s);
}

希望有帮助!

strlen(ClientSendBuf)毫无意义(它是一个未初始化的字符**,似乎他想在其中填充二进制数据)。@nos:ClientSendBuf是一个字符*。同意strlen的说法,尽管ClientSendBuf被声明为
char*ClientSendBuf[sizeof(msg)]
-一个char*数组,当用于此上下文(作为strlen的参数)时,它使
ClientSendBuf
成为char**@nos:哦,是的,你说得对。有一段时间没有看到C代码了;)这里可能只需要删除ClientSendBuff,只需执行
string\t buffer={(char*)&msg,sizeof msg}buffer.s
视为字符串,或从该函数返回
buffer
。是否只需初始化
buffer.s
以指向
msg
的原始表示?(与例如先将msg.numb转换为文本相反?)。请记住strlen在C字符串上工作。此代码中没有字符串。@否:是!!!但是我需要发送整个结构(基本上包含很多不同的成员类型,包括其他结构)。所以我想我从一个简单的开始,一个包含整数作为结构成员的结构,然后将所有内容复制到缓冲区。我不需要关心little-endian/big-endian,因为客户端服务器在同一台机器上。@Yodha:是的,对不起,我试图简化一些东西,但我自己都弄糊涂了。最后我需要一个字符串数组,因为struct msg的成员应该包含不同类型的成员(uint32_t、str、int等)。所以我需要将整个结构复制到一个缓冲区,并使用其他只接受字符串类型的API发送它。@metallicprade:是的,对不起,我试图简化一些东西,但我自己都弄糊涂了。最后我需要一个字符串数组,因为struct msg的成员应该包含不同类型的成员(uint32_t、str、int等)。所以我需要将整个结构复制到一个缓冲区,并使用其他只接受字符串类型的API发送它。除了答案中已经说过的,将sizeof与structs一起使用通常是一个非常糟糕的主意,因为一个结构(或联合)可以在其中的任何位置包含填充字节,除了第一个元素。除非有防止填充的保护机制,否则永远不要编写这样的代码。这种保护机制的例子是处理器前检查或断言。或者至少是一个带有注释的部分,描述特定编译器如何处理填充以及代码如何依赖填充。