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一起使用通常是一个非常糟糕的主意,因为一个结构(或联合)可以在其中的任何位置包含填充字节,除了第一个元素。除非有防止填充的保护机制,否则永远不要编写这样的代码。这种保护机制的例子是处理器前检查或断言。或者至少是一个带有注释的部分,描述特定编译器如何处理填充以及代码如何依赖填充。