我正在尝试创建一个具有固定大小字符串的可变长度数组的结构。
struct foo_query{
char tag[10];
int value_count;
char * values[VAL_SIZE];
};
现在,我想创建一个这些结构的数组,并为这些值分配一些内存:
#define buffer(a) (char *) malloc(sizeof(char[a][VAL_SIZE]))
foo_query queries[total_queries] = {
{"FOO", 25, buffer(25)},
{"BAR", 21, buffer(21)}
};
#undef buffer
最后,我想实际向这些值写入一些数据。
query_index = 0;
for(int i = 0; i < queries.value_count; i++){
strncpy(queries[query_index].values[i], "Hello", VAL_SIZE);
Serial.outln("success");
}
但最后一点失败了。success
被打印一两次,然后一切都停止了。
据我所知,内存已经分配好了,我没有溢出任何东西,那么为什么代码会崩溃呢?
基本上您的内存分配是错误的。
foo_query queries[total_queries] = {
{"FOO", 25, buffer(25)},
{"BAR", 21, buffer(21)}
};
当您在上面创建queries
时,您只填充values
的第一个元素,因为按照您的定义,values
是char *
的数组。
如果i
大于0,当您将值放入该数组时,您正在复制到一个未分配的指针中。
strncpy(queries[query_index].values[i], "Hello", VAL_SIZE);
当i
大于0时,queries[query_index].values[i]
可能为NULL,也可能指向内存的某个部分。无论哪种方式,它都会导致未定义的行为和代码随机崩溃。
假设您正试图将VAL_SIZE
字符复制到其中,那么看起来更有可能您实际上错误地定义了values
。与char *
的数组相比,您更可能在寻找指向VAL_SIZE
的char
数组的指针?如果是这种情况,您需要将其定义为:
char (* values)[VAL_SIZE];
它还可以与您使用malloc
分配的相当奇怪的内存量相匹配,而malloc(sizeof(char[VAL_SIZE})*(a))
看起来更清晰。(注意:始终将宏参数包装在括号中,以确保不会出现疯狂的优先级问题,即buffer(10+10)
在没有括号的情况下变成malloc(sizeof(char[VAL_SIZE})*10+10)
)。
你仍然应该添加
queries[query_index].values[i][VAL_SIZE-1]=' ';
在strncpy
之后,只是为了确保如果要复制的字符串太大而无法容纳,那么您的字符串也会以NUL终止。