我正在尝试使用固定大小字符串的可变长度数组创建一个结构。
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
打印一次或两次,然后一切都停止。
据我所知,内存已经分配,我没有溢出任何东西,为什么代码会崩溃?
答案 0 :(得分:0)
基本上你的内存分配是错误的。
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 *
的数组,您看起来更有可能寻找指向char
VAL_SIZE
数组的指针?如果是这种情况,您需要将其定义为:
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]='\0';
在strncpy
之后,只是为了确保复制的字符串太大而不适合,你的字符串也终止NUL。